Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/java/BinaryConstantPool.java
38918 views
1
/*
2
* Copyright (c) 1994, 2013, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.tools.java;
27
28
import java.io.IOException;
29
import java.io.DataInputStream;
30
import java.io.DataOutputStream;
31
import java.util.Vector;
32
import java.util.Hashtable;
33
34
/**
35
* This class is used to represent a constant table once
36
* it is read from a class file.
37
*
38
* WARNING: The contents of this source file are not part of any
39
* supported API. Code that depends on them does so at its own risk:
40
* they are subject to change or removal without notice.
41
*/
42
public final
43
class BinaryConstantPool implements Constants {
44
private byte types[];
45
private Object cpool[];
46
47
/**
48
* Constructor
49
*/
50
BinaryConstantPool(DataInputStream in) throws IOException {
51
// JVM 4.1 ClassFile.constant_pool_count
52
types = new byte[in.readUnsignedShort()];
53
cpool = new Object[types.length];
54
for (int i = 1 ; i < cpool.length ; i++) {
55
int j = i;
56
// JVM 4.4 cp_info.tag
57
switch(types[i] = in.readByte()) {
58
case CONSTANT_UTF8:
59
cpool[i] = in.readUTF();
60
break;
61
62
case CONSTANT_INTEGER:
63
cpool[i] = new Integer(in.readInt());
64
break;
65
case CONSTANT_FLOAT:
66
cpool[i] = new Float(in.readFloat());
67
break;
68
case CONSTANT_LONG:
69
cpool[i++] = new Long(in.readLong());
70
break;
71
case CONSTANT_DOUBLE:
72
cpool[i++] = new Double(in.readDouble());
73
break;
74
75
case CONSTANT_CLASS:
76
case CONSTANT_STRING:
77
// JVM 4.4.3 CONSTANT_String_info.string_index
78
// or JVM 4.4.1 CONSTANT_Class_info.name_index
79
cpool[i] = new Integer(in.readUnsignedShort());
80
break;
81
82
case CONSTANT_FIELD:
83
case CONSTANT_METHOD:
84
case CONSTANT_INTERFACEMETHOD:
85
case CONSTANT_NAMEANDTYPE:
86
// JVM 4.4.2 CONSTANT_*ref_info.class_index & name_and_type_index
87
cpool[i] = new Integer((in.readUnsignedShort() << 16) | in.readUnsignedShort());
88
break;
89
90
case CONSTANT_METHODHANDLE:
91
cpool[i] = readBytes(in, 3);
92
break;
93
case CONSTANT_METHODTYPE:
94
cpool[i] = readBytes(in, 2);
95
break;
96
case CONSTANT_INVOKEDYNAMIC:
97
cpool[i] = readBytes(in, 4);
98
break;
99
100
case 0:
101
default:
102
throw new ClassFormatError("invalid constant type: " + (int)types[i]);
103
}
104
}
105
}
106
107
private byte[] readBytes(DataInputStream in, int cnt) throws IOException {
108
byte[] b = new byte[cnt];
109
in.readFully(b);
110
return b;
111
}
112
113
/**
114
* get a integer
115
*/
116
public int getInteger(int n) {
117
return (n == 0) ? 0 : ((Number)cpool[n]).intValue();
118
}
119
120
/**
121
* get a value
122
*/
123
public Object getValue(int n) {
124
return (n == 0) ? null : cpool[n];
125
}
126
127
/**
128
* get a string
129
*/
130
public String getString(int n) {
131
return (n == 0) ? null : (String)cpool[n];
132
}
133
134
/**
135
* get an identifier
136
*/
137
public Identifier getIdentifier(int n) {
138
return (n == 0) ? null : Identifier.lookup(getString(n));
139
}
140
141
/**
142
* get class declaration
143
*/
144
public ClassDeclaration getDeclarationFromName(Environment env, int n) {
145
return (n == 0) ? null : env.getClassDeclaration(Identifier.lookup(getString(n).replace('/','.')));
146
}
147
148
/**
149
* get class declaration
150
*/
151
public ClassDeclaration getDeclaration(Environment env, int n) {
152
return (n == 0) ? null : getDeclarationFromName(env, getInteger(n));
153
}
154
155
/**
156
* get a type from a type signature
157
*/
158
public Type getType(int n) {
159
return Type.tType(getString(n));
160
}
161
162
/**
163
* get the type of constant given an index
164
*/
165
public int getConstantType(int n) {
166
return types[n];
167
}
168
169
/**
170
* get the n-th constant from the constant pool
171
*/
172
public Object getConstant(int n, Environment env) {
173
int constant_type = getConstantType(n);
174
switch (constant_type) {
175
case CONSTANT_INTEGER:
176
case CONSTANT_FLOAT:
177
case CONSTANT_LONG:
178
case CONSTANT_DOUBLE:
179
case CONSTANT_METHODHANDLE:
180
case CONSTANT_METHODTYPE:
181
case CONSTANT_INVOKEDYNAMIC:
182
return getValue(n);
183
184
case CONSTANT_CLASS:
185
return getDeclaration(env, n);
186
187
case CONSTANT_STRING:
188
return getString(getInteger(n));
189
190
case CONSTANT_FIELD:
191
case CONSTANT_METHOD:
192
case CONSTANT_INTERFACEMETHOD:
193
try {
194
int key = getInteger(n);
195
ClassDefinition clazz =
196
getDeclaration(env, key >> 16).getClassDefinition(env);
197
int name_and_type = getInteger(key & 0xFFFF);
198
Identifier id = getIdentifier(name_and_type >> 16);
199
Type type = getType(name_and_type & 0xFFFF);
200
201
for (MemberDefinition field = clazz.getFirstMatch(id);
202
field != null;
203
field = field.getNextMatch()) {
204
Type field_type = field.getType();
205
if ((constant_type == CONSTANT_FIELD)
206
? (field_type == type)
207
: (field_type.equalArguments(type)))
208
return field;
209
}
210
} catch (ClassNotFound e) {
211
}
212
return null;
213
214
default:
215
throw new ClassFormatError("invalid constant type: " +
216
constant_type);
217
}
218
}
219
220
221
/**
222
* Get a list of dependencies, ie: all the classes referenced in this
223
* constant pool.
224
*/
225
public Vector getDependencies(Environment env) {
226
Vector v = new Vector();
227
for (int i = 1 ; i < cpool.length ; i++) {
228
switch(types[i]) {
229
case CONSTANT_CLASS:
230
v.addElement(getDeclarationFromName(env, getInteger(i)));
231
break;
232
}
233
}
234
return v;
235
}
236
237
Hashtable indexHashObject, indexHashAscii;
238
Vector MoreStuff;
239
240
/**
241
* Find the index of an Object in the constant pool
242
*/
243
public int indexObject(Object obj, Environment env) {
244
if (indexHashObject == null)
245
createIndexHash(env);
246
Integer result = (Integer)indexHashObject.get(obj);
247
if (result == null)
248
throw new IndexOutOfBoundsException("Cannot find object " + obj + " of type " +
249
obj.getClass() + " in constant pool");
250
return result.intValue();
251
}
252
253
/**
254
* Find the index of an ascii string in the constant pool. If it's not in
255
* the constant pool, then add it at the end.
256
*/
257
public int indexString(String string, Environment env) {
258
if (indexHashObject == null)
259
createIndexHash(env);
260
Integer result = (Integer)indexHashAscii.get(string);
261
if (result == null) {
262
if (MoreStuff == null) MoreStuff = new Vector();
263
result = new Integer(cpool.length + MoreStuff.size());
264
MoreStuff.addElement(string);
265
indexHashAscii.put(string, result);
266
}
267
return result.intValue();
268
}
269
270
/**
271
* Create a hash table of all the items in the constant pool that could
272
* possibly be referenced from the outside.
273
*/
274
275
public void createIndexHash(Environment env) {
276
indexHashObject = new Hashtable();
277
indexHashAscii = new Hashtable();
278
for (int i = 1; i < cpool.length; i++) {
279
if (types[i] == CONSTANT_UTF8) {
280
indexHashAscii.put(cpool[i], new Integer(i));
281
} else {
282
try {
283
indexHashObject.put(getConstant(i, env), new Integer(i));
284
} catch (ClassFormatError e) { }
285
}
286
}
287
}
288
289
290
/**
291
* Write out the contents of the constant pool, including any additions
292
* that have been added.
293
*/
294
public void write(DataOutputStream out, Environment env) throws IOException {
295
int length = cpool.length;
296
if (MoreStuff != null)
297
length += MoreStuff.size();
298
out.writeShort(length);
299
for (int i = 1 ; i < cpool.length; i++) {
300
int type = types[i];
301
Object x = cpool[i];
302
out.writeByte(type);
303
switch (type) {
304
case CONSTANT_UTF8:
305
out.writeUTF((String) x);
306
break;
307
case CONSTANT_INTEGER:
308
out.writeInt(((Number)x).intValue());
309
break;
310
case CONSTANT_FLOAT:
311
out.writeFloat(((Number)x).floatValue());
312
break;
313
case CONSTANT_LONG:
314
out.writeLong(((Number)x).longValue());
315
i++;
316
break;
317
case CONSTANT_DOUBLE:
318
out.writeDouble(((Number)x).doubleValue());
319
i++;
320
break;
321
case CONSTANT_CLASS:
322
case CONSTANT_STRING:
323
out.writeShort(((Number)x).intValue());
324
break;
325
case CONSTANT_FIELD:
326
case CONSTANT_METHOD:
327
case CONSTANT_INTERFACEMETHOD:
328
case CONSTANT_NAMEANDTYPE: {
329
int value = ((Number)x).intValue();
330
out.writeShort(value >> 16);
331
out.writeShort(value & 0xFFFF);
332
break;
333
}
334
case CONSTANT_METHODHANDLE:
335
case CONSTANT_METHODTYPE:
336
case CONSTANT_INVOKEDYNAMIC:
337
out.write((byte[])x, 0, ((byte[])x).length);
338
break;
339
default:
340
throw new ClassFormatError("invalid constant type: "
341
+ (int)types[i]);
342
}
343
}
344
for (int i = cpool.length; i < length; i++) {
345
String string = (String)(MoreStuff.elementAt(i - cpool.length));
346
out.writeByte(CONSTANT_UTF8);
347
out.writeUTF(string);
348
}
349
}
350
351
}
352
353