1 package org.metricshub.jawk.intermediate;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.io.Serializable;
26 import java.util.function.Supplier;
27 import org.metricshub.jawk.ext.ExtensionFunction;
28
29
30
31
32
33
34
35
36
37
38
39
40
41 class Tuple implements Serializable {
42
43 private static final long serialVersionUID = 8105941219003992817L;
44 private Opcode opcode;
45 private long[] ints = new long[4];
46 private boolean[] bools = new boolean[4];
47 private double[] doubles = new double[4];
48 private String[] strings = new String[4];
49 private Class<?>[] types = new Class[4];
50 private Address address = null;
51 private Class<?> cls = null;
52 private transient Supplier<Address> addressSupplier = null;
53 private int lineno = -1;
54 private Tuple next = null;
55 private ExtensionFunction extensionFunction;
56
57 Tuple(Opcode opcode) {
58 this.opcode = opcode;
59 }
60
61 Tuple(Opcode opcode, long i1) {
62 this(opcode);
63 ints[0] = i1;
64 types[0] = Long.class;
65 }
66
67 Tuple(Opcode opcode, long i1, long i2) {
68 this(opcode, i1);
69 ints[1] = i2;
70 types[1] = Long.class;
71 }
72
73 Tuple(Opcode opcode, long i1, boolean b2) {
74 this(opcode, i1);
75 bools[1] = b2;
76 types[1] = Boolean.class;
77 }
78
79 Tuple(Opcode opcode, long i1, boolean b2, boolean b3) {
80 this(opcode, i1, b2);
81 bools[2] = b3;
82 types[2] = Boolean.class;
83 }
84
85 Tuple(Opcode opcode, double d1) {
86 this(opcode);
87 doubles[0] = d1;
88 types[0] = Double.class;
89 }
90
91 Tuple(Opcode opcode, String s1) {
92 this(opcode);
93 strings[0] = s1;
94 types[0] = String.class;
95 }
96
97 Tuple(Opcode opcode, boolean b1) {
98 this(opcode);
99 bools[0] = b1;
100 types[0] = Boolean.class;
101 }
102
103 Tuple(Opcode opcode, String s1, long i2) {
104 this(opcode, s1);
105 ints[1] = i2;
106 types[1] = Long.class;
107 }
108
109 Tuple(Opcode opcode, Address address) {
110 this(opcode);
111 this.address = address;
112 types[0] = Address.class;
113 }
114
115 Tuple(Opcode opcode, String strarg, long intarg, boolean boolarg) {
116 this(opcode, strarg, intarg);
117 bools[2] = boolarg;
118 types[2] = Boolean.class;
119 }
120
121 Tuple(Opcode opcode, ExtensionFunction function, long intarg, boolean boolarg) {
122 this(opcode);
123 this.extensionFunction = function;
124 types[0] = ExtensionFunction.class;
125 ints[1] = intarg;
126 types[1] = Long.class;
127 bools[2] = boolarg;
128 types[2] = Boolean.class;
129 }
130
131 Tuple(Opcode opcode, Supplier<Address> addressSupplier, String s2, long i3, long i4) {
132 this(opcode);
133 this.addressSupplier = addressSupplier;
134 strings[1] = s2;
135 types[1] = String.class;
136 ints[2] = i3;
137 types[2] = Long.class;
138 ints[3] = i4;
139 types[3] = Long.class;
140 }
141
142 Tuple(Opcode opcode, Class<?> cls) {
143 this(opcode);
144 this.cls = cls;
145 types[0] = Class.class;
146 }
147
148 Tuple(Opcode opcode, String s1, String s2) {
149 this(opcode, s1);
150 strings[1] = s2;
151 types[1] = String.class;
152 }
153
154 boolean hasNext() {
155 return next != null;
156 }
157
158 Tuple getNext() {
159 return next;
160 }
161
162 void setNext(Tuple next) {
163 this.next = next;
164 }
165
166 void setLineNumber(int lineNumber) {
167 assert this.lineno == -1 : "The line number was already set to " + this.lineno + ". Later lineno = "
168 + lineNumber + ".";
169 this.lineno = lineNumber;
170 }
171
172 @Override
173 public String toString() {
174 StringBuilder sb = new StringBuilder();
175 sb.append(opcode.name());
176 int idx = 0;
177 while ((idx < types.length) && (types[idx] != null)) {
178 sb.append(", ");
179 Class<?> type = types[idx];
180 if (type == Long.class) {
181 sb.append(ints[idx]);
182 } else if (type == Boolean.class) {
183 sb.append(bools[idx]);
184 } else if (type == Double.class) {
185 sb.append(doubles[idx]);
186 } else if (type == String.class) {
187 sb.append('"').append(strings[idx]).append('"');
188 } else if (type == Address.class) {
189 assert idx == 0;
190 sb.append(address);
191 } else if (type == ExtensionFunction.class) {
192 assert idx == 0;
193 sb.append(extensionFunction.getKeyword());
194 } else if (type == Class.class) {
195 assert idx == 0;
196 sb.append(cls);
197 } else {
198 throw new Error("Unknown param type (" + idx + "): " + type);
199 }
200 ++idx;
201 }
202 return sb.toString();
203 }
204
205 public void touch(java.util.List<Tuple> queue) {
206 assert lineno != -1 : "The line number should have been set by queue.add(), but was not.";
207 if (addressSupplier != null) {
208 address = addressSupplier.get();
209 types[0] = Address.class;
210 }
211 if (address != null) {
212 if (address.index() == -1) {
213 throw new Error("address " + address + " is unresolved");
214 }
215 if (address.index() >= queue.size()) {
216 throw new Error("address " + address + " doesn't resolve to an actual list element");
217 }
218 }
219 }
220
221 Opcode getOpcode() {
222 return opcode;
223 }
224
225 long[] getInts() {
226 return ints;
227 }
228
229 boolean[] getBools() {
230 return bools;
231 }
232
233 double[] getDoubles() {
234 return doubles;
235 }
236
237 String[] getStrings() {
238 return strings;
239 }
240
241 Class<?>[] getTypes() {
242 return types;
243 }
244
245 Address getAddress() {
246 return address;
247 }
248
249 Class<?> getCls() {
250 return cls;
251 }
252
253 Supplier<Address> getAddressSupplier() {
254 return addressSupplier;
255 }
256
257 ExtensionFunction getExtensionFunction() {
258 return extensionFunction;
259 }
260
261 void setAddress(Address address) {
262 this.address = address;
263 }
264
265 int getLineno() {
266 return lineno;
267 }
268 }