Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/runtime/InvocationTests/shared/GenericClassGenerator.java
40948 views
1
/*
2
* Copyright (c) 2009, 2019, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
package shared;
26
27
import jdk.internal.org.objectweb.asm.ClassWriter;
28
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
29
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
30
import jdk.internal.org.objectweb.asm.MethodVisitor;
31
import static jdk.internal.org.objectweb.asm.Opcodes.*;
32
import static shared.AccessCheck.*;
33
34
public class GenericClassGenerator<T extends GenericClassGenerator> {
35
private static final String targetMethodName = Utils.TARGET_METHOD_NAME;
36
37
private int flags = 0;
38
private ClassWriter writer;
39
private String fullClassName = null;
40
private String parentClassName = null;
41
42
/*******************************************************************/
43
public GenericClassGenerator(String fullClassName) {
44
this(fullClassName, "java/lang/Object");
45
}
46
47
/*******************************************************************/
48
public GenericClassGenerator(String fullClassName, String parentClassName ) {
49
this(fullClassName, parentClassName, ACC_PUBLIC);
50
}
51
52
/*******************************************************************/
53
public GenericClassGenerator(String fullClassName, String parentClassName, int flags) {
54
this(fullClassName, parentClassName, flags, new String[0]);
55
}
56
57
/*******************************************************************/
58
public GenericClassGenerator(String fullClassName, String parentClassName, int flags, String[] implementedInterfaces) {
59
writer = new ClassWriter(COMPUTE_FRAMES | COMPUTE_MAXS);
60
61
this.fullClassName = fullClassName;
62
this.flags = flags;
63
64
// Construct simple class
65
if (parentClassName != null) {
66
this.parentClassName = getInternalName(parentClassName);
67
} else {
68
this.parentClassName = "java/lang/Object";
69
}
70
71
String parent = this.parentClassName;
72
String name = getInternalName(fullClassName);
73
74
if (Utils.isACC_SUPER) {
75
flags = flags | ACC_SUPER;
76
}
77
78
writer.visit(Utils.version, flags, name, null, parent, implementedInterfaces);
79
80
// Add constructor
81
if ( !isInterface(flags) ) {
82
MethodVisitor m =
83
writer.visitMethod(
84
ACC_PUBLIC
85
, "<init>"
86
, "()V"
87
, null
88
, null
89
);
90
91
m.visitCode();
92
m.visitVarInsn(ALOAD, 0);
93
m.visitMethodInsn(
94
INVOKESPECIAL
95
, getInternalName(parent)
96
, "<init>"
97
, "()V"
98
);
99
m.visitInsn(RETURN);
100
m.visitEnd();
101
m.visitMaxs(0,0);
102
}
103
}
104
105
/*******************************************************************/
106
protected static String getInternalName(String fullClassName) {
107
return fullClassName.replaceAll("\\.", "/");
108
}
109
110
/*******************************************************************/
111
public T addTargetConstructor(AccessType access) {
112
// AccessType.UNDEF means that the target method isn't defined, so do nothing
113
if (access == AccessType.UNDEF || isInterface(flags) ) {
114
return (T)this;
115
}
116
117
// Add target constructor
118
int methodAccessType = access.value();
119
120
MethodVisitor m =
121
writer.visitMethod(
122
methodAccessType
123
, "<init>"
124
, "(I)V"
125
, null
126
, null
127
);
128
129
// Add a call to parent constructor
130
m.visitCode();
131
m.visitVarInsn(ALOAD, 0);
132
m.visitMethodInsn(
133
INVOKESPECIAL
134
, getInternalName(parentClassName)
135
, "<init>"
136
, "()V"
137
);
138
139
// Add result reporting
140
String shortName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
141
m.visitLdcInsn(shortName+".<init>");
142
m.visitFieldInsn(
143
PUTSTATIC
144
, "Result"
145
, "value"
146
, "Ljava/lang/String;"
147
);
148
149
m.visitInsn(RETURN);
150
m.visitEnd();
151
m.visitMaxs(0,0);
152
153
return (T)this;
154
155
}
156
157
/*******************************************************************/
158
public T addTargetMethod(AccessType access) {
159
return addTargetMethod(access, 0);
160
}
161
162
/*******************************************************************/
163
public T addTargetMethod(AccessType access, int additionalFlags) {
164
// AccessType.UNDEF means that the target method isn't defined, so do nothing
165
if (access == AccessType.UNDEF) {
166
return (T)this;
167
}
168
169
// Add target method
170
int methodAccessType = access.value();
171
if ( isInterface(flags) || isAbstract(flags) ) {
172
methodAccessType |= ACC_ABSTRACT;
173
}
174
175
// Skip method declaration for abstract private case, which doesn't pass
176
// classfile verification stage
177
if ( isPrivate(methodAccessType) && isAbstract(methodAccessType) ) {
178
return (T)this;
179
}
180
181
MethodVisitor m =
182
writer.visitMethod(
183
methodAccessType | additionalFlags
184
, targetMethodName
185
, "()Ljava/lang/String;"
186
, null
187
, null
188
);
189
190
// Don't generate body if the method is abstract
191
if ( (methodAccessType & ACC_ABSTRACT) == 0 ) {
192
String shortName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
193
194
// Simply returns info about itself
195
m.visitCode();
196
m.visitLdcInsn(shortName+"."+targetMethodName);
197
m.visitInsn(ARETURN);
198
m.visitEnd();
199
m.visitMaxs(0,0);
200
}
201
202
return (T)this;
203
}
204
205
/*******************************************************************/
206
public T addField(int access, String name, String type) {
207
writer.visitField(
208
access
209
, name
210
, getInternalName(type)
211
, null
212
, null
213
)
214
.visitEnd();
215
216
return (T)this;
217
}
218
219
/*******************************************************************/
220
// Add target method call site into current class
221
public T addCaller(String targetClass, int callType) {
222
MethodVisitor m = writer.visitMethod(
223
ACC_PUBLIC | ACC_STATIC
224
, "call"
225
, String.format( "(L%s;)Ljava/lang/String;" , getInternalName(targetClass))
226
, null
227
, null
228
);
229
230
m.visitCode();
231
m.visitVarInsn(ALOAD, 0);
232
m.visitMethodInsn(
233
callType
234
, getInternalName(targetClass)
235
, targetMethodName
236
, "()Ljava/lang/String;"
237
);
238
m.visitInsn(ARETURN);
239
m.visitEnd();
240
m.visitMaxs(0,0);
241
242
return (T)this;
243
}
244
245
/*******************************************************************/
246
public byte[] getClassFile() {
247
writer.visitEnd();
248
return writer.toByteArray();
249
}
250
251
/*******************************************************************/
252
public String getFullClassName() {
253
return fullClassName;
254
}
255
}
256
257