null
52 | */
53 | public Class> getClassTag() {
54 | return classTag;
55 | }
56 |
57 | /**
58 | * Looks for a tag.
59 | * @param tag tag-byte
60 | * @return tag
61 | */
62 | public static Tag lookupByTag(final byte tag) {
63 | Tag tTag = null;
64 | for (final Tag loopTag : values()) {
65 | if (loopTag.tag == tag) {
66 | tTag = loopTag;
67 | break;
68 | }
69 | }
70 | return tTag;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMArrayID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Array-id.
5 | */
6 | public class VMArrayID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param arrayId array-id
11 | */
12 | public VMArrayID(final long arrayId) {
13 | super(arrayId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMArrayRegion.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Region of an array.
5 | */
6 | public class VMArrayRegion extends VMDataField {
7 |
8 | /** type of the array */
9 | private Tag tag;
10 | /** values */
11 | private VMDataField[] values;
12 |
13 | /**
14 | * Constructor
15 | * @param tag type of the array
16 | * @param values values
17 | */
18 | public VMArrayRegion(final Tag tag, final VMDataField[] values) {
19 | this.tag = tag;
20 | this.values = values;
21 | }
22 |
23 | /**
24 | * Gets the type of the value.
25 | * @return tag
26 | */
27 | public Tag getTag() {
28 | return tag;
29 | }
30 |
31 | /**
32 | * Gets the values.
33 | * @return values
34 | */
35 | public VMDataField[] getValue() {
36 | return values;
37 | }
38 |
39 | /** {@inheritDoc} */
40 | @Override
41 | public int length() {
42 | int len = 1 + 4;
43 | for (VMDataField vmDataField : values) {
44 | len += vmDataField.length();
45 | }
46 | return len;
47 | }
48 |
49 | /** {@inheritDoc} */
50 | @Override
51 | public void write(byte[] buf, int pOffset) {
52 | int offset = pOffset;
53 | buf[offset] = tag.getTag();
54 | offset++;
55 |
56 | final VMInt vmLen = new VMInt(values.length);
57 | vmLen.write(buf, offset);
58 | offset += 4;
59 |
60 | for (VMDataField value : values) {
61 | value.write(buf, offset);
62 | offset += value.length();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMArrayTypeID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * ArrayType-id.
5 | */
6 | public class VMArrayTypeID extends VMReferenceTypeID {
7 |
8 | /**
9 | * Constructor
10 | * @param arrayTypeId array-type-id
11 | */
12 | public VMArrayTypeID(final long arrayTypeId) {
13 | super(arrayTypeId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMBoolean.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * boolean VM-value.
5 | */
6 | public class VMBoolean extends VMByte {
7 |
8 | /**
9 | * Constructor
10 | * @param b byte-value of boolean
11 | */
12 | public VMBoolean(final boolean b) {
13 | super(b ? (byte) 1 : 0);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMByte.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * 8-bit VM-value.
5 | */
6 | public class VMByte extends VMDataField {
7 |
8 | /** byte-value */
9 | private final byte value;
10 |
11 | /**
12 | * Constructor
13 | * @param value byte-value
14 | */
15 | public VMByte(final byte value) {
16 | this.value = value;
17 | }
18 |
19 | /**
20 | * Gets the byte-value.
21 | * @return byte
22 | */
23 | public byte getValue() {
24 | return value;
25 | }
26 |
27 | /** {@inheritDoc} */
28 | @Override
29 | public int length() {
30 | return 1;
31 | }
32 |
33 | /** {@inheritDoc} */
34 | @Override
35 | public String toString() {
36 | return new StringBuilder(20).append(getClass().getSimpleName()).append('(').append(value).append(')').toString();
37 | }
38 |
39 | /** {@inheritDoc} */
40 | @Override
41 | public void write(byte[] buf, int offset) {
42 | buf[offset] = value;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMClassID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Class-id.
5 | */
6 | public class VMClassID extends VMReferenceTypeID {
7 |
8 | /**
9 | * Constructor
10 | * @param classId class-id
11 | */
12 | public VMClassID(final long classId) {
13 | super(classId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMClassLoaderID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * ClassLoader-id.
5 | */
6 | public class VMClassLoaderID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param classLoaderId classLoader-id
11 | */
12 | public VMClassLoaderID(final long classLoaderId) {
13 | super(classLoaderId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMClassObjectID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * VM-class-object-ID.
5 | */
6 | public class VMClassObjectID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param classObjectId ID
11 | */
12 | public VMClassObjectID(final long classObjectId) {
13 | super(classObjectId);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMDataField.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * VM-data-field.
5 | */
6 | public abstract class VMDataField {
7 |
8 | /**
9 | * Gets the length of the value.
10 | * @return length in bytes
11 | */
12 | public abstract int length();
13 |
14 | /**
15 | * Writes the field into a buffer.
16 | * @param buf buffer
17 | * @param offset offset in buffer
18 | */
19 | public abstract void write(byte[] buf, int offset);
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMFieldID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Field-id.
5 | */
6 | public class VMFieldID extends VMReferenceTypeID {
7 |
8 | /**
9 | * Constructor
10 | * @param fieldId field-id
11 | */
12 | public VMFieldID(final long fieldId) {
13 | super(fieldId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMFrameID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Frame-id.
5 | */
6 | public class VMFrameID extends VMReferenceTypeID {
7 |
8 | /**
9 | * Constructor
10 | * @param frameId frame-id
11 | */
12 | public VMFrameID(final long frameId) {
13 | super(frameId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMInt.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * 32-bit VM-value.
5 | */
6 | public class VMInt extends VMDataField {
7 |
8 | /** int-value */
9 | private final int value;
10 |
11 | /**
12 | * Constructor
13 | * @param value int-value
14 | */
15 | public VMInt(final int value) {
16 | this.value = value;
17 | }
18 |
19 | /**
20 | * Gets the int-value.
21 | * @return int
22 | */
23 | public int getValue() {
24 | return value;
25 | }
26 |
27 | /** {@inheritDoc} */
28 | @Override
29 | public int length() {
30 | return 4;
31 | }
32 |
33 | /** {@inheritDoc} */
34 | @Override
35 | public void write(byte[] buf, int offset) {
36 | buf[offset] = (byte) (value >> 24);
37 | buf[offset + 1] = (byte) ((value >> 16) & 0xff);
38 | buf[offset + 2] = (byte) ((value >> 8) & 0xff);
39 | buf[offset + 3] = (byte) (value & 0xff);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMInterfaceID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Interface-id.
5 | */
6 | public class VMInterfaceID extends VMReferenceTypeID {
7 |
8 | /**
9 | * Constructor
10 | * @param interfaceId interface-id
11 | */
12 | public VMInterfaceID(final long interfaceId) {
13 | super(interfaceId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMLong.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * 64-bit VM-value.
5 | */
6 | public class VMLong extends VMDataField {
7 |
8 | /** long-value */
9 | private final long value;
10 |
11 | /**
12 | * Constructor
13 | * @param value long-value
14 | */
15 | public VMLong(final long value) {
16 | this.value = value;
17 | }
18 |
19 | /**
20 | * Gets the long-value.
21 | * @return long
22 | */
23 | public long getValue() {
24 | return value;
25 | }
26 |
27 | /** {@inheritDoc} */
28 | @Override
29 | public int length() {
30 | return 8;
31 | }
32 |
33 | /** {@inheritDoc} */
34 | @Override
35 | public void write(byte[] buf, int offset) {
36 | buf[offset] = (byte) (value >> 56);
37 | buf[offset + 1] = (byte) ((value >> 48) & 0xff);
38 | buf[offset + 2] = (byte) ((value >> 40) & 0xff);
39 | buf[offset + 3] = (byte) ((value >> 32) & 0xff);
40 | buf[offset + 4] = (byte) ((value >> 24) & 0xff);
41 | buf[offset + 5] = (byte) ((value >> 16) & 0xff);
42 | buf[offset + 6] = (byte) ((value >> 8) & 0xff);
43 | buf[offset + 7] = (byte) (value & 0xff);
44 | }
45 |
46 | /** {@inheritDoc} */
47 | @Override
48 | public String toString() {
49 | return new StringBuilder(20).append(getClass().getSimpleName()).append('(').append(value).append(')').toString();
50 | }
51 |
52 | /** {@inheritDoc} */
53 | @Override
54 | public int hashCode() {
55 | final int prime = 31;
56 | int result = 1;
57 | result = prime * result + (int) (value ^ (value >>> 32));
58 | return result;
59 | }
60 |
61 | /** {@inheritDoc} */
62 | @Override
63 | public boolean equals(Object obj) {
64 | if (this == obj) {
65 | return true;
66 | }
67 | if (obj == null) {
68 | return false;
69 | }
70 | if (!(obj instanceof VMLong)) {
71 | return false;
72 | }
73 | VMLong other = (VMLong) obj;
74 | if (value != other.value) {
75 | return false;
76 | }
77 | return true;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMMethodID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Method-id.
5 | */
6 | public class VMMethodID extends VMReferenceTypeID {
7 |
8 | /**
9 | * Constructor
10 | * @param methodId method-id
11 | */
12 | public VMMethodID(final long methodId) {
13 | super(methodId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMObjectID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Object-id.
5 | */
6 | public class VMObjectID extends VMLong {
7 |
8 | /**
9 | * Constructor
10 | * @param objectId object-id
11 | */
12 | public VMObjectID(final long objectId) {
13 | super(objectId);
14 | }
15 |
16 | /** {@inheritDoc} */
17 | @Override
18 | public String toString() {
19 | return new StringBuilder(20).append(getClass().getSimpleName()).append('(').append("0x").append(Long.toHexString(getValue())).append(')').toString();
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMObjectOrExceptionID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Newly created object or exception.
5 | */
6 | public class VMObjectOrExceptionID {
7 |
8 | /** object-id */
9 | private final VMTaggedObjectId vmObjectID;
10 | /** exception-id */
11 | private final VMTaggedObjectId vmExceptionID;
12 |
13 | /**
14 | * Constructor
15 | * @param vmObjectID object-id or null
16 | * @param vmExceptionID exception-id or null
17 | */
18 | public VMObjectOrExceptionID(final VMTaggedObjectId vmObjectID, final VMTaggedObjectId vmExceptionID) {
19 | this.vmObjectID = vmObjectID;
20 | this.vmExceptionID = vmExceptionID;
21 | }
22 |
23 | /**
24 | * Gets the object-id.
25 | * @return tagged-object-id or null
26 | */
27 | public VMTaggedObjectId getVmObjectID() {
28 | return vmObjectID;
29 | }
30 |
31 | /**
32 | * Gets the exception-id.
33 | * @return tagged-object-id or null
34 | */
35 | public VMTaggedObjectId getVmExceptionID() {
36 | return vmExceptionID;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMReferenceTypeID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Object-id.
5 | */
6 | public class VMReferenceTypeID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param objectId object-id
11 | */
12 | public VMReferenceTypeID(final long objectId) {
13 | super(objectId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMShort.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * 16-bit VM-value.
5 | */
6 | public class VMShort extends VMDataField {
7 |
8 | /** short-value */
9 | private final short value;
10 |
11 | /**
12 | * Constructor
13 | * @param value short-value
14 | */
15 | public VMShort(final short value) {
16 | this.value = value;
17 | }
18 |
19 | /**
20 | * Gets the short-value.
21 | * @return short
22 | */
23 | public short getValue() {
24 | return value;
25 | }
26 |
27 | /** {@inheritDoc} */
28 | @Override
29 | public int length() {
30 | return 2;
31 | }
32 |
33 | /** {@inheritDoc} */
34 | @Override
35 | public void write(byte[] buf, int offset) {
36 | buf[offset] = (byte) (value >> 8);
37 | buf[offset + 1] = (byte) (value & 0xff);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMString.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | import java.nio.charset.StandardCharsets;
4 |
5 | /**
6 | * UTF-8-string.
7 | */
8 | public class VMString extends VMDataField {
9 |
10 | /** string-value */
11 | private final String value;
12 |
13 | /** UTF-8-value */
14 | private final byte[] bufValue;
15 |
16 | /**
17 | * Constructor
18 | * @param value string-value
19 | */
20 | public VMString(final String value) {
21 | if (value == null) {
22 | throw new IllegalArgumentException("String null is not valid.");
23 | }
24 | this.value = value;
25 | bufValue = value.getBytes(StandardCharsets.UTF_8);
26 | }
27 |
28 | /**
29 | * Gets the string-value.
30 | * @return string
31 | */
32 | public String getValue() {
33 | return value;
34 | }
35 |
36 | /** {@inheritDoc} */
37 | @Override
38 | public int length() {
39 | return 4 + bufValue.length;
40 | }
41 |
42 | /** {@inheritDoc} */
43 | @Override
44 | public void write(byte[] buf, int offset) {
45 | final int len = bufValue.length;
46 | buf[offset] = (byte) (len >> 24);
47 | buf[offset + 1] = (byte) ((len >> 16) & 0xff);
48 | buf[offset + 2] = (byte) ((len >> 8) & 0xff);
49 | buf[offset + 3] = (byte) (len & 0xff);
50 | System.arraycopy(bufValue, 0, buf, offset + 4, len);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMStringID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * String-id.
5 | */
6 | public class VMStringID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param stringId string-id
11 | */
12 | public VMStringID(final long stringId) {
13 | super(stringId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMTaggedObjectId.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Tagged Object-id.
5 | */
6 | public class VMTaggedObjectId extends VMValue {
7 |
8 | /** null-object */
9 | public static final VMTaggedObjectId NULL = new VMTaggedObjectId(new VMObjectID(0l));
10 |
11 | /**
12 | * Constructor
13 | * @param value value of VMObjectID
14 | */
15 | public VMTaggedObjectId(final VMObjectID value) {
16 | super(Tag.OBJECT.getTag(), value);
17 | }
18 |
19 | /**
20 | * Constructor
21 | * @param tag JDWP-tag
22 | * @param value value of VMObjectID
23 | */
24 | public VMTaggedObjectId(final Tag tag, final VMObjectID value) {
25 | super(tag.getTag(), value);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMThreadGroupID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * ThreadGroup-id.
5 | */
6 | public class VMThreadGroupID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param threadGroupId threadGroup-id
11 | */
12 | public VMThreadGroupID(final long threadGroupId) {
13 | super(threadGroupId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMThreadID.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Thread-id.
5 | */
6 | public class VMThreadID extends VMObjectID {
7 |
8 | /**
9 | * Constructor
10 | * @param threadId thread-id
11 | */
12 | public VMThreadID(final long threadId) {
13 | super(threadId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMValue.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * Object-id.
5 | */
6 | public class VMValue extends VMDataField {
7 |
8 | /** type of the value */
9 | private byte tag;
10 | /** value */
11 | private VMDataField value;
12 |
13 | /**
14 | * Constructor
15 | * @param tag type of the value
16 | * @param value value of VMObjectID
17 | */
18 | public VMValue(final byte tag, final VMDataField value) {
19 | this.tag = tag;
20 | this.value = value;
21 | }
22 |
23 | /**
24 | * Gets the type of the value.
25 | * @return tag
26 | */
27 | public byte getTag() {
28 | return tag;
29 | }
30 |
31 | /**
32 | * Gets the value
33 | * @return value
34 | */
35 | public VMDataField getValue() {
36 | return value;
37 | }
38 |
39 | /** {@inheritDoc} */
40 | @Override
41 | public int length() {
42 | return 1 + value.length();
43 | }
44 |
45 | /** {@inheritDoc} */
46 | @Override
47 | public void write(byte[] buf, int offset) {
48 | buf[offset] = tag;
49 | value.write(buf, offset + 1);
50 | }
51 |
52 | /** {@inheritDoc} */
53 | @Override
54 | public String toString() {
55 | return new StringBuilder(20).append(getClass().getSimpleName())
56 | .append("(tag:").append(Tag.lookupByTag(tag))
57 | .append(", value:").append(value).append(')').toString();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/VMVoid.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.datatypes;
2 |
3 | /**
4 | * 0-bit VM-value.
5 | */
6 | public class VMVoid extends VMDataField {
7 |
8 | /**
9 | * Constructor
10 | */
11 | public VMVoid() {
12 | // no value
13 | }
14 |
15 | /** {@inheritDoc} */
16 | @Override
17 | public int length() {
18 | return 0;
19 | }
20 |
21 | /** {@inheritDoc} */
22 | @Override
23 | public void write(byte[] buf, int offset) {
24 | // no value to write
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/datatypes/package-info.java:
--------------------------------------------------------------------------------
1 | /** VM-datatypes */
2 | package org.rogmann.jsmud.datatypes;
3 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/DebuggerException.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | /**
4 | * Exception while executing the debugger.
5 | */
6 | public class DebuggerException extends RuntimeException {
7 |
8 | /** Serialization-Id */
9 | private static final long serialVersionUID = 20210331L;
10 |
11 | /**
12 | * Constructor
13 | * @param msg exception-message
14 | */
15 | public DebuggerException(final String msg) {
16 | super(msg);
17 | }
18 |
19 | /**
20 | * Constructor
21 | * @param msg exception-message
22 | * @param e cause-throwable
23 | */
24 | public DebuggerException(final String msg, Throwable e) {
25 | super(msg, e);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/DebuggerInterface.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | import java.io.IOException;
4 |
5 | import org.rogmann.jsmud.datatypes.VMDataField;
6 |
7 | /**
8 | * Interface of the debugger-command-processor.
9 | */
10 | public interface DebuggerInterface {
11 |
12 | /**
13 | * Processes a set of packets.
14 | * @throws IOException in case of an IO-error
15 | */
16 | void processPackets() throws IOException;
17 |
18 | /**
19 | * Sends an event in an event-command-set.
20 | * @param policy suspend-policy
21 | * @param eventType event-type
22 | * @param fields fields of the event
23 | * @return id of command
24 | * @throws IOException in case of an io-error
25 | */
26 | int sendVMEvent(final JdwpSuspendPolicy policy, VMEventType eventType, VMDataField... fields) throws IOException;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/DebuggerJvmVisitorProvider.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | import java.util.concurrent.ConcurrentHashMap;
4 | import java.util.concurrent.ConcurrentMap;
5 |
6 | import org.rogmann.jsmud.events.JdwpEventRequest;
7 | import org.rogmann.jsmud.log.Logger;
8 | import org.rogmann.jsmud.log.LoggerFactory;
9 | import org.rogmann.jsmud.vm.ClassRegistry;
10 | import org.rogmann.jsmud.vm.JvmExecutionVisitor;
11 | import org.rogmann.jsmud.vm.JvmExecutionVisitorProvider;
12 |
13 | /**
14 | * JVM-debugger-visitor provider.
15 | */
16 | public class DebuggerJvmVisitorProvider implements JvmExecutionVisitorProvider {
17 | /** logger */
18 | private static final Logger LOGGER = LoggerFactory.getLogger(DebuggerJvmVisitorProvider.class);
19 |
20 | /** number of instructions to be logged in detail */
21 | private final int maxInstrLogged;
22 |
23 | /** number of method-invocations to be logged in detail */
24 | private final int maxMethodsLogged;
25 |
26 | /** optional source-file-requester */
27 | private final SourceFileRequester sourceFileRequester;
28 |
29 | /** map from request-id to event-request */
30 | private final ConcurrentMapnull
68 | */
69 | public static JdwpCommandSet lookupByKind(final byte number) {
70 | return ((number & 0xff) < A_CS.length) ? A_CS[number] : null;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/JdwpErrorCode.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | /**
4 | * jwdp-error-code.
5 | */
6 | public enum JdwpErrorCode {
7 |
8 | /** No error has occurred. */
9 | NONE(0),
10 | /** Passed thread is null, is not a valid thread or has exited. */
11 | INVALID_THREAD(10),
12 | /** Thread group invalid. */
13 | INVALID_THREAD_GROUP(11),
14 | /** If the specified thread has not been suspended by an event. */
15 | THREAD_NOT_SUSPENDED(13),
16 | /** Thread already suspended. */
17 | THREAD_SUSPENDED(14),
18 | /** If this reference type has been unloaded and garbage collected. */
19 | INVALID_OBJECT(20),
20 | /** Invalid class. */
21 | INVALID_CLASS(21),
22 | /** Invalid method. */
23 | INVALID_METHODID(23),
24 | /** Invalid field. */
25 | INVALID_FIELDID(25),
26 | /** Invalid jFrameID. */
27 | INVALID_FRAMEID(30),
28 | /** Invalid slot. */
29 | INVALID_SLOT(35),
30 | /** The functionality is not implemented in this virtual machine. */
31 | NOT_IMPLEMENTED(99),
32 | /** Invalid pointer. */
33 | NULL_POINTER(100),
34 | /** Desired information is not available. */
35 | ABSENT_INFORMATION(101),
36 | /** The specified event type id is not recognized. */
37 | INVALID_EVENT_TYPE(102),
38 | /** Illegal Argument. */
39 | ILLEGAL_ARGUMENT(103),
40 | /** The function needed to allocate memory and no more memory was available for allocation. */
41 | OUT_OF_MEMORY(110),
42 | /** The virtual machine is not running. */
43 | VM_DEAD(112),
44 | /** Invalid Length. */
45 | INVALID_LENGTH(504),
46 | /** Invalid String. */
47 | INVALID_STRING(506),
48 | /** Invalid Array. */
49 | INVALID_ARRAY(508);
50 |
51 | /** error-code */
52 | private final short errorCode;
53 |
54 | /**
55 | * Constructor
56 | * @param errorCode error-code
57 | */
58 | private JdwpErrorCode(final int errorCode) {
59 | this.errorCode = (short) errorCode;
60 | }
61 |
62 | /**
63 | * Gets the error-code.
64 | * @return error-code
65 | */
66 | public short getErrorCode() {
67 | return errorCode;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/JdwpSuspendPolicy.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | /**
4 | * jwdp-suspend-policy.
5 | */
6 | public enum JdwpSuspendPolicy {
7 |
8 | /** Suspend no threads when this event is encountered. */
9 | NONE(0),
10 | /** Suspend the event thread when this event is encountered. */
11 | EVENT_THREAD(1),
12 | /** Suspend all threads when this event is encountered. */
13 | ALL(2);
14 |
15 | /** suspend-policy */
16 | private final byte policy;
17 |
18 | /**
19 | * Internal constructor
20 | * @param policy suspend-policy
21 | */
22 | private JdwpSuspendPolicy(final int policy) {
23 | this.policy = (byte) policy;
24 | }
25 |
26 | /**
27 | * Gets the suspend-policy.
28 | * @return suspend-policy
29 | */
30 | public byte getPolicy() {
31 | return policy;
32 | }
33 |
34 | /**
35 | * Lookups a suspend-policy
36 | * @param bSuspendPolicy suspend-poliy
37 | * @return suspend-policy or null
38 | */
39 | public static JdwpSuspendPolicy lookupBySuspendPolicy(final byte bSuspendPolicy) {
40 | for (JdwpSuspendPolicy loopPolicy : values()) {
41 | if (loopPolicy.policy == bSuspendPolicy) {
42 | return loopPolicy;
43 | }
44 | }
45 | return null;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/JvmClinitWhileDebuggingException.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | import org.rogmann.jsmud.vm.JvmException;
4 |
5 | /**
6 | * This exception is thrown when a clinit-method (static initializer)
7 | * should be invoke while processing debugger-packages.
8 | *
9 | * Example: Invoking of $$EnhancerByCGLIB$$3d7dcd21.hashCode triggers a clinit-method.
10 | */ 11 | public class JvmClinitWhileDebuggingException extends JvmException { 12 | 13 | /** serialization-id */ 14 | private static final long serialVersionUID = 20220203L; 15 | 16 | /** 17 | * Constructor 18 | * @param message message-text 19 | */ 20 | public JvmClinitWhileDebuggingException(final String message) { 21 | super(message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/debugger/MethodFrameDebugContext.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.debugger; 2 | 3 | import org.rogmann.jsmud.events.JdwpEventRequest; 4 | import org.rogmann.jsmud.events.JdwpModifierStep; 5 | import org.rogmann.jsmud.vm.MethodFrame; 6 | 7 | /** 8 | * Debugger-context of a method-frame. 9 | */ 10 | public class MethodFrameDebugContext { 11 | 12 | /** method-frame */ 13 | final MethodFrame frame; 14 | 15 | /** current STEP-event-request */ 16 | JdwpEventRequest eventRequestStep; 17 | 18 | /** current STEP-OUT-event-request for parent frame */ 19 | JdwpEventRequest eventRequestStepUp; 20 | 21 | /** current STEP-modifier */ 22 | JdwpModifierStep modStep; 23 | 24 | /** current STEP-OUT-modifier for parent frame */ 25 | JdwpModifierStep modStepUp; 26 | 27 | /** line of step-start */ 28 | int stepLine; 29 | 30 | /** 31 | * Constructor 32 | * @param frame method-frame 33 | */ 34 | public MethodFrameDebugContext(final MethodFrame frame) { 35 | this.frame = frame; 36 | } 37 | 38 | /** {@inheritDoc} */ 39 | @Override 40 | public String toString() { 41 | final StringBuilder sb = new StringBuilder(12); 42 | sb.append("MFDC#").append(Integer.toHexString(System.identityHashCode(this))); 43 | return sb.toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/debugger/SlotRequest.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.debugger; 2 | 3 | /** 4 | * Index and tag of a variable-slot in a method-frame. 5 | */ 6 | public class SlotRequest { 7 | 8 | /** variable's index in the frame */ 9 | private final int slot; 10 | /** type of the variable */ 11 | private final byte tag; 12 | 13 | /** 14 | * Constructor 15 | * @param slot variable's index 16 | * @param tag type of the variable 17 | */ 18 | public SlotRequest(int slot, byte tag) { 19 | this.slot = slot; 20 | this.tag = tag; 21 | } 22 | 23 | /** 24 | * Gets the variable's index in the frame. 25 | * @return index 26 | */ 27 | public int getSlot() { 28 | return slot; 29 | } 30 | 31 | /** 32 | * Gets the type of the variale. 33 | * @return tag 34 | */ 35 | public byte getTag() { 36 | return tag; 37 | } 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/debugger/SlotValue.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.debugger; 2 | 3 | import org.rogmann.jsmud.datatypes.VMValue; 4 | 5 | /** 6 | * Index and value of a variable-slot in a method-frame. 7 | */ 8 | public class SlotValue { 9 | 10 | /** variable's index in the frame */ 11 | private final int slot; 12 | /** type and value of the variable */ 13 | private final VMValue variable; 14 | 15 | /** 16 | * Constructor 17 | * @param slot variable's index 18 | * @param variable type and value of the variable 19 | */ 20 | public SlotValue(int slot, VMValue variable) { 21 | this.slot = slot; 22 | this.variable= variable; 23 | } 24 | 25 | /** 26 | * Gets the variable's index in the frame. 27 | * @return index 28 | */ 29 | public int getSlot() { 30 | return slot; 31 | } 32 | 33 | /** 34 | * Gets the type and value of the variale. 35 | * @return tag and value 36 | */ 37 | public VMValue getVariable() { 38 | return variable; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/debugger/SourceFileRequester.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.debugger; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.IOException; 5 | 6 | /** 7 | * Interface to request the on-the-fly-generation of pseudo-byte-code of java-classes. 8 | */ 9 | public interface SourceFileRequester { 10 | 11 | /** 12 | * Checks if a source-file should be generated 13 | * @param clazzLoaded loaded class 14 | * @returntrue
if a source-file is requested
15 | */
16 | boolean isSourceRequested(Class> clazzLoaded);
17 |
18 | /**
19 | * Creates a buffered writer for writing pseudo-code
20 | * @param clazz class
21 | * @return writer
22 | * @throws IOException in case of an IO-error
23 | */
24 | BufferedWriter createBufferedWriter(Class> clazz) throws IOException;
25 |
26 | /**
27 | * line-break (CR of CRLF) of generated source-file.
28 | * @return line-break
29 | */
30 | String lineBreak();
31 |
32 | /**
33 | * Extension of a generated file.
34 | * @return extension, e.g. "java" or "asm"
35 | */
36 | String getExtension();
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/SourceFilesLocalDirectory.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.debugger;
2 |
3 | import java.io.BufferedWriter;
4 | import java.io.File;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.io.OutputStreamWriter;
8 | import java.nio.charset.Charset;
9 | import java.nio.file.Files;
10 | import java.util.function.Predicate;
11 |
12 | import org.rogmann.jsmud.vm.Utils;
13 |
14 | /**
15 | * Generation of source-files into a local directory.
16 | */
17 | public class SourceFilesLocalDirectory implements SourceFileRequester {
18 |
19 | /** class-filter */
20 | private final Predicatenull
60 | */
61 | public static VMEventType lookupByKind(byte kind) {
62 | for (VMEventType type : values()) {
63 | if (type.eventKind == kind) {
64 | return type;
65 | }
66 | }
67 | return null;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/debugger/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * JDWP-based debugger.
3 | *
4 | * {@link org.rogmann.jsmud.debugger.JdwpCommandProcessor} is the central class in this package.
5 | *{@link org.rogmann.jsmud.debugger.DebuggerJvmVisitor} is the link to the JVM-simulation.
6 | * 7 | */ 8 | package org.rogmann.jsmud.debugger; -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/events/JdwpEventModifier.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.events; 2 | 3 | /** 4 | * Abstract base-class of a event-modifier. 5 | */ 6 | public abstract class JdwpEventModifier { 7 | 8 | /** modifier kind */ 9 | private final ModKind modKind; 10 | 11 | /** 12 | * Constructor 13 | * @param modKind modifier kind 14 | */ 15 | protected JdwpEventModifier(final ModKind modKind) { 16 | this.modKind = modKind; 17 | } 18 | 19 | /** 20 | * Gets the modifier kind. 21 | * @return modifier kind 22 | */ 23 | public ModKind getModKind() { 24 | return modKind; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/events/JdwpEventRequest.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.events; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.rogmann.jsmud.debugger.JdwpSuspendPolicy; 7 | import org.rogmann.jsmud.debugger.VMEventType; 8 | 9 | /** 10 | * Details of an event-request. 11 | */ 12 | public class JdwpEventRequest { 13 | 14 | /** request-id */ 15 | private final int requestId; 16 | 17 | /** event-type */ 18 | private final VMEventType eventType; 19 | /** suspend-policy */ 20 | private final JdwpSuspendPolicy suspendPolicy; 21 | 22 | /** modifiers */ 23 | private final Listnull
56 | */
57 | public static ModKind lookupByKind(byte bModKind) {
58 | for (ModKind modKind : values()) {
59 | if (modKind.modKind == bModKind) {
60 | return modKind;
61 | }
62 | }
63 | return null;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/events/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Package containing event-requests.
3 | */
4 | package org.rogmann.jsmud.events;
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/gen/JsmudGeneratedClasses.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.gen;
2 |
3 | /**
4 | * Marker-class of folder containing generated classes.
5 | */
6 | public final class JsmudGeneratedClasses {
7 |
8 | /**
9 | * Internal Constructor.
10 | */
11 | private JsmudGeneratedClasses() {
12 | // internal
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/gen/package-info.java:
--------------------------------------------------------------------------------
1 | /** Folder to store classes generated at runtime */
2 | package org.rogmann.jsmud.gen;
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/log/Logger.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.log;
2 |
3 | /**
4 | * logger.
5 | */
6 | public interface Logger {
7 |
8 | /**
9 | * Checks if the logger is enabled for debug-level.
10 | * @return debug-flag
11 | */
12 | boolean isDebugEnabled();
13 |
14 | /**
15 | * Log a message at debug-level.
16 | * @param msg message
17 | */
18 | void debug(String msg);
19 |
20 | /**
21 | * Checks if the logger is enabled for info-level.
22 | * @return info-flag
23 | */
24 | boolean isInfoEnabled();
25 |
26 | /**
27 | * Log a message at info-level.
28 | * @param msg message
29 | */
30 | void info(String msg);
31 |
32 | /**
33 | * Log a message at error-level.
34 | * @param msg message
35 | */
36 | void error(String msg);
37 |
38 | /**
39 | * Log a message at error-level.
40 | * @param msg message
41 | * @param t throwable
42 | */
43 | void error(String msg, Throwable t);
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/log/LoggerFactory.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.log;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 | import java.util.Iterator;
5 | import java.util.ServiceLoader;
6 | import java.util.concurrent.atomic.AtomicReference;
7 |
8 | import org.rogmann.jsmud.vm.JvmException;
9 |
10 | /** logger-factory */
11 | public class LoggerFactory {
12 | /** property-name */
13 | public static final String PROPERTY_NAME = LoggerSpi.class.getName();
14 |
15 | /** logger-SPI */
16 | private static final AtomicReferenceYou may implement LoggerSpi to support your preferred logger (SLJ4J, Log4j2, ...).
5 | */ 6 | package org.rogmann.jsmud.log; -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/replydata/LineCodeIndex.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.replydata; 2 | 3 | /** 4 | * Initial index of a source-line. 5 | */ 6 | public class LineCodeIndex { 7 | 8 | /** line-code index */ 9 | private final long lineCodeIndex; 10 | /* line-number */ 11 | private final int lineNumber; 12 | 13 | /** 14 | * Constructor 15 | * @param lineCodeIndex line-code index 16 | * @param lineNumber line-number 17 | */ 18 | public LineCodeIndex(long lineCodeIndex, int lineNumber) { 19 | this.lineCodeIndex = lineCodeIndex; 20 | this.lineNumber = lineNumber; 21 | } 22 | 23 | /** 24 | * Gets the line-code index 25 | * @return index 26 | */ 27 | public long getLineCodeIndex() { 28 | return lineCodeIndex; 29 | } 30 | 31 | /** 32 | * Gets the line-number. 33 | * @return line-number 34 | */ 35 | public int getLineNumber() { 36 | return lineNumber; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/rogmann/jsmud/replydata/LineTable.java: -------------------------------------------------------------------------------- 1 | package org.rogmann.jsmud.replydata; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Line-table of a method. 7 | */ 8 | public class LineTable { 9 | 10 | /** lowest valid index of the method */ 11 | private final long start; 12 | /** highest valid index of the method */ 13 | private final long end; 14 | /** list of line-numbers */ 15 | private final Listnull
37 | */
38 | public static TypeTag lookupByKind(byte bTag) {
39 | for (TypeTag typeTag : values()) {
40 | if (typeTag.tag == bTag) {
41 | return typeTag;
42 | }
43 | }
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/replydata/VariableSlot.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.replydata;
2 |
3 | /**
4 | * Information of a variable in a method.
5 | */
6 | public class VariableSlot {
7 |
8 | /** first code index at which the variable is visible */
9 | private final long codeIndex;
10 |
11 | /** variable's name */
12 | private final String name;
13 |
14 | /** JNI-signature of the type of the variable */
15 | private final String signature;
16 |
17 | /** generic signature or empty string */
18 | private final String genericSignature;
19 |
20 | /** length of variable-visibility beginning at codeIndex */
21 | private final int length;
22 |
23 | /** index of variable in its frame */
24 | private final int slot;
25 |
26 | /**
27 | * Constructor
28 | * @param codeIndex first code index at which the variable is visible
29 | * @param name variable's name
30 | * @param signature JNI-signature of the type of the variable
31 | * @param genericSignature generic signature or empty string
32 | * @param length length of variable-visibility beginning at codeIndex
33 | * @param slot index of variable in its frame
34 | */
35 | public VariableSlot(long codeIndex, String name, String signature, String genericSignature, int length, int slot) {
36 | this.codeIndex = codeIndex;
37 | this.name = name;
38 | this.signature = signature;
39 | this.genericSignature = genericSignature;
40 | this.length = length;
41 | this.slot = slot;
42 | }
43 |
44 | /**
45 | * Gets the first code index at which the variable is visible.
46 | * @return codeIndex
47 | */
48 | public long getCodeIndex() {
49 | return codeIndex;
50 | }
51 |
52 | /**
53 | * Gets the variable's name.
54 | * @return name
55 | */
56 | public String getName() {
57 | return name;
58 | }
59 |
60 | /**
61 | * @return signature JNI-signature of the type of the variable
62 | */
63 | public String getSignature() {
64 | return signature;
65 | }
66 |
67 | /**
68 | * Gets the generic signature or empty string.
69 | * @return genericSignature
70 | */
71 | public String getGenericSignature() {
72 | return genericSignature;
73 | }
74 |
75 | /**
76 | * Gets the length of variable-visibility beginning at codeIndex.
77 | * @return length
78 | */
79 | public int getLength() {
80 | return length;
81 | }
82 |
83 | /**
84 | * Gets the slot index of variable in its frame.
85 | * @return slot index
86 | */
87 | public int getSlot() {
88 | return slot;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/replydata/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Helper-classes for transfering reply-data.
3 | */
4 | package org.rogmann.jsmud.replydata;
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/ExpressionArrayLoad.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | import org.objectweb.asm.tree.InsnNode;
4 |
5 | /**
6 | * Expression loading an array-element.
7 | */
8 | public class ExpressionArrayLoad extends ExpressionBasenull
if unknown
24 | */
25 | @SuppressWarnings("static-method")
26 | public Type getType() {
27 | return null;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/ExpressionCastPrimitive.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | import org.objectweb.asm.Type;
4 | import org.objectweb.asm.tree.InsnNode;
5 |
6 | /**
7 | * Cast-expression with primitive type.
8 | */
9 | public class ExpressionCastPrimitive extends ExpressionBasenull
in case of a finally-block
19 | * @param sourceNameRenderer source-name renderer
20 | */
21 | public ExpressionException(final Type typeException, final SourceNameRenderer sourceNameRenderer) {
22 | super(null);
23 | this.typeException = typeException;
24 | this.sourceNameRenderer = sourceNameRenderer;
25 | }
26 |
27 | /** {@inheritDoc} */
28 | @Override
29 | public void render(StringBuilder sb) {
30 | if (typeException != null) {
31 | final String className = sourceNameRenderer.renderType(typeException);
32 | sb.append("catched ").append(className);
33 | }
34 | else {
35 | final Type typeThrowable = Type.getType(Throwable.class);
36 | sb.append("finally ").append(sourceNameRenderer.renderType(typeThrowable));
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/ExpressionGetField.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | import org.objectweb.asm.tree.ClassNode;
4 | import org.objectweb.asm.tree.FieldInsnNode;
5 |
6 | /**
7 | * Field-instruction which gets a field of an object-instance.
8 | */
9 | public class ExpressionGetField extends ExpressionBasenull
in case of INVOKESTATIC)
25 | * @param exprArgs arguments of method
26 | */
27 | public ExpressionInvoke(MethodInsnNode insn, SourceNameRenderer sourceNameRenderer, final ExpressionBase> exprObj,
28 | final ExpressionBase>... exprArgs) {
29 | super(insn);
30 | this.sourceNameRenderer = sourceNameRenderer;
31 | this.exprObj = exprObj;
32 | this.exprArgs = exprArgs;
33 | }
34 |
35 | /** {@inheritDoc} */
36 | @Override
37 | public Type getType() {
38 | return Type.getReturnType(insn.desc);
39 | }
40 |
41 | /** {@inheritDoc} */
42 | @Override
43 | public void render(StringBuilder sb) {
44 | if (insn.getOpcode() == Opcodes.INVOKESTATIC) {
45 | final String className = insn.owner.replace('/', '.');
46 | sb.append(sourceNameRenderer.renderClassName(className));
47 | }
48 | else {
49 | exprObj.render(sb);
50 | }
51 | sb.append('.');
52 | sb.append(insn.name);
53 | sb.append('(');
54 | boolean isFirst = true;
55 | for (final ExpressionBase> arg : exprArgs) {
56 | if (isFirst) {
57 | isFirst = false;
58 | }
59 | else {
60 | sb.append(", ");
61 | }
62 | arg.render(sb);
63 | }
64 | sb.append(')');
65 | }
66 |
67 | /** {@inheritDoc} */
68 | @Override
69 | public String toString() {
70 | return String.format("%s(%s%s);",
71 | getClass().getSimpleName(),
72 | insn.name, insn.desc);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/ExpressionMultiNewarray.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | import org.objectweb.asm.Type;
4 | import org.objectweb.asm.tree.MultiANewArrayInsnNode;
5 |
6 | /**
7 | * Type-instruction ANEWARRAY.
8 | */
9 | public class ExpressionMultiNewarray extends ExpressionBasetrue
if a pseudo NEW-instruction may be rendered */
19 | private final boolean isNewRenderingAllowed;
20 |
21 | /**
22 | * Constructor
23 | * @param insn type-instruction, e.g. NEW
24 | * @param classNode class-node
25 | * @param isNewRenderingAllowed true
if a pseudo NEW-instruction may be rendered (necessary at difficult constructor-arguments)
26 | */
27 | public ExpressionTypeInstr(final TypeInsnNode insn, final ClassNode classNode,
28 | final boolean isNewRenderingAllowed) {
29 | super(insn);
30 | this.classNode = classNode;
31 | this.isNewRenderingAllowed = isNewRenderingAllowed;
32 | }
33 |
34 | /** {@inheritDoc} */
35 | @Override
36 | public void render(StringBuilder sb) {
37 | final int opcode = insn.getOpcode();
38 | if (opcode == Opcodes.NEW) {
39 | if (!isNewRenderingAllowed) {
40 | throw new SourceRuntimeException("The NEW-instruction should be rendered at INVOKESPECIAL true
if a class-name may be imported */
28 | private final Predicatetrue
if a class-name may be imported
34 | */
35 | public SourceNameRenderer(final String classPackage, final Predicatetrue
if the statement is visible in the generated source-file.
10 | * @return visible-flag
11 | */
12 | @SuppressWarnings("static-method")
13 | public boolean isVisible() {
14 | return true;
15 | }
16 |
17 | /**
18 | * Renders an expression or instruction.
19 | * @param sb string-builder
20 | */
21 | public abstract void render(final StringBuilder sb);
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/StatementComment.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | /**
4 | * Block comment.
5 | */
6 | public class StatementComment extends StatementBase {
7 |
8 | private final String comment;
9 |
10 | /**
11 | * Constructor
12 | * @param comment comment to be rendered
13 | */
14 | public StatementComment(final String comment) {
15 | this.comment = comment;
16 | }
17 |
18 | /** {@inheritDoc} */
19 | @Override
20 | public void render(StringBuilder sb) {
21 | sb.append("/** ");
22 | if (comment != null) {
23 | sb.append(comment.replace("*/", "*°/"));
24 | }
25 | sb.append(" */");
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/StatementConstructor.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | import org.objectweb.asm.tree.ClassNode;
4 | import org.objectweb.asm.tree.MethodInsnNode;
5 |
6 | /**
7 | * Execution of a constructor (e.g. super or this) without new.
8 | */
9 | public class StatementConstructor extends StatementInstrnull
in case of INVOKESTATIC)
24 | * @param exprArgs arguments of method
25 | */
26 | public StatementInvoke(final MethodInsnNode insn, final SourceNameRenderer sourceNameRenderer,
27 | final ExpressionBase> exprObj,
28 | final ExpressionBase>... exprArgs) {
29 | super(insn);
30 | this.sourceNameRenderer = sourceNameRenderer;
31 | this.exprObj = exprObj;
32 | this.exprArgs = exprArgs;
33 | }
34 |
35 | /** {@inheritDoc} */
36 | @Override
37 | public void render(StringBuilder sb) {
38 | if (insn.getOpcode() == Opcodes.INVOKESTATIC) {
39 | final String className = insn.owner.replace('/', '.');
40 | sb.append(sourceNameRenderer.renderClassName(className));
41 | }
42 | else {
43 | exprObj.render(sb);
44 | }
45 | sb.append('.');
46 | sb.append(insn.name);
47 | sb.append('(');
48 | boolean isFirst = true;
49 | for (final ExpressionBase> arg : exprArgs) {
50 | if (isFirst) {
51 | isFirst = false;
52 | }
53 | else {
54 | sb.append(", ");
55 | }
56 | arg.render(sb);
57 | }
58 | sb.append(')');
59 | sb.append(';');
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/org/rogmann/jsmud/source/StatementLabel.java:
--------------------------------------------------------------------------------
1 | package org.rogmann.jsmud.source;
2 |
3 | import java.util.Map;
4 |
5 | import org.objectweb.asm.Label;
6 | import org.objectweb.asm.tree.LabelNode;
7 |
8 | /**
9 | * Label (possible destination of goto-instruction).
10 | */
11 | public class StatementLabel extends StatementInstr