1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInput;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.util.Arrays;
23
24 import org.apache.bcel.Const;
25 import org.apache.bcel.util.Args;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public final class StackMap extends Attribute {
47
48 private StackMapEntry[] table;
49
50
51
52
53
54
55
56
57
58
59 StackMap(final int nameIndex, final int length, final DataInput dataInput, final ConstantPool constantPool) throws IOException {
60 this(nameIndex, length, (StackMapEntry[]) null, constantPool);
61 final int mapLength = dataInput.readUnsignedShort();
62 table = new StackMapEntry[mapLength];
63 for (int i = 0; i < mapLength; i++) {
64 table[i] = new StackMapEntry(dataInput, constantPool);
65 }
66 }
67
68
69
70
71
72
73
74
75
76
77 public StackMap(final int nameIndex, final int length, final StackMapEntry[] table, final ConstantPool constantPool) {
78 super(Const.ATTR_STACK_MAP, nameIndex, length, constantPool);
79 this.table = table != null ? table : StackMapEntry.EMPTY_ARRAY;
80 Args.requireU2(this.table.length, "table.length");
81 }
82
83
84
85
86
87
88
89 @Override
90 public void accept(final Visitor v) {
91 v.visitStackMap(this);
92 }
93
94
95
96
97 @Override
98 public Attribute copy(final ConstantPool constantPool) {
99 final StackMap c = (StackMap) clone();
100 c.table = new StackMapEntry[table.length];
101 Arrays.setAll(c.table, i -> table[i].copy());
102 c.setConstantPool(constantPool);
103 return c;
104 }
105
106
107
108
109
110
111
112 @Override
113 public void dump(final DataOutputStream file) throws IOException {
114 super.dump(file);
115 file.writeShort(table.length);
116 for (final StackMapEntry entry : table) {
117 entry.dump(file);
118 }
119 }
120
121 public int getMapLength() {
122 return table.length;
123 }
124
125
126
127
128 public StackMapEntry[] getStackMap() {
129 return table;
130 }
131
132
133
134
135 public void setStackMap(final StackMapEntry[] table) {
136 this.table = table != null ? table : StackMapEntry.EMPTY_ARRAY;
137 int len = 2;
138 for (final StackMapEntry element : this.table) {
139 len += element.getMapEntrySize();
140 }
141 setLength(len);
142 }
143
144
145
146
147 @Override
148 public String toString() {
149 final StringBuilder buf = new StringBuilder("StackMap(");
150 int runningOffset = -1;
151 for (int i = 0; i < table.length; i++) {
152 runningOffset = table[i].getByteCodeOffset() + runningOffset + 1;
153 buf.append(String.format("%n@%03d %s", runningOffset, table[i]));
154 if (i < table.length - 1) {
155 buf.append(", ");
156 }
157 }
158 buf.append(')');
159 return buf.toString();
160 }
161 }