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