Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java
41159 views
1
/*
2
* Copyright (c) 2005, 2021, 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.reflect.misc;
27
28
import java.io.EOFException;
29
import java.security.AllPermission;
30
import java.security.AccessController;
31
import java.security.PermissionCollection;
32
import java.security.SecureClassLoader;
33
import java.security.PrivilegedExceptionAction;
34
import java.security.CodeSource;
35
import java.io.InputStream;
36
import java.io.BufferedInputStream;
37
import java.io.IOException;
38
import java.net.URL;
39
import java.net.URLConnection;
40
import java.lang.reflect.Method;
41
import java.lang.reflect.InvocationTargetException;
42
import java.lang.reflect.Modifier;
43
import java.util.Arrays;
44
import java.util.HashMap;
45
import java.util.Map;
46
47
48
class Trampoline {
49
static {
50
if (Trampoline.class.getClassLoader() == null) {
51
throw new Error(
52
"Trampoline must not be defined by the bootstrap classloader");
53
}
54
}
55
56
@SuppressWarnings("removal")
57
private static void ensureInvocableMethod(Method m)
58
throws InvocationTargetException
59
{
60
Class<?> clazz = m.getDeclaringClass();
61
if (clazz.equals(AccessController.class) ||
62
clazz.equals(Method.class) ||
63
clazz.getName().startsWith("java.lang.invoke."))
64
throw new InvocationTargetException(
65
new UnsupportedOperationException("invocation not supported"));
66
}
67
68
private static Object invoke(Method m, Object obj, Object[] params)
69
throws InvocationTargetException, IllegalAccessException
70
{
71
ensureInvocableMethod(m);
72
return m.invoke(obj, params);
73
}
74
}
75
76
/*
77
* Create a trampoline class.
78
*/
79
public final class MethodUtil extends SecureClassLoader {
80
private static final String MISC_PKG = "sun.reflect.misc.";
81
private static final String TRAMPOLINE = MISC_PKG + "Trampoline";
82
private static final Method bounce = getTrampoline();
83
84
private MethodUtil() {
85
super();
86
}
87
88
public static Method getMethod(Class<?> cls, String name, Class<?>[] args)
89
throws NoSuchMethodException {
90
ReflectUtil.checkPackageAccess(cls);
91
return cls.getMethod(name, args);
92
}
93
94
public static Method[] getMethods(Class<?> cls) {
95
ReflectUtil.checkPackageAccess(cls);
96
return cls.getMethods();
97
}
98
99
/*
100
* Discover the public methods on public classes
101
* and interfaces accessible to any caller by calling
102
* Class.getMethods() and walking towards Object until
103
* we're done.
104
*/
105
@SuppressWarnings("removal")
106
public static Method[] getPublicMethods(Class<?> cls) {
107
// compatibility for update release
108
if (System.getSecurityManager() == null) {
109
return cls.getMethods();
110
}
111
Map<Signature, Method> sigs = new HashMap<Signature, Method>();
112
while (cls != null) {
113
boolean done = getInternalPublicMethods(cls, sigs);
114
if (done) {
115
break;
116
}
117
getInterfaceMethods(cls, sigs);
118
cls = cls.getSuperclass();
119
}
120
return sigs.values().toArray(new Method[sigs.size()]);
121
}
122
123
/*
124
* Process the immediate interfaces of this class or interface.
125
*/
126
private static void getInterfaceMethods(Class<?> cls,
127
Map<Signature, Method> sigs) {
128
Class<?>[] intfs = cls.getInterfaces();
129
for (int i=0; i < intfs.length; i++) {
130
Class<?> intf = intfs[i];
131
boolean done = getInternalPublicMethods(intf, sigs);
132
if (!done) {
133
getInterfaceMethods(intf, sigs);
134
}
135
}
136
}
137
138
/*
139
*
140
* Process the methods in this class or interface
141
*/
142
private static boolean getInternalPublicMethods(Class<?> cls,
143
Map<Signature, Method> sigs) {
144
Method[] methods = null;
145
try {
146
/*
147
* This class or interface is non-public so we
148
* can't use any of it's methods. Go back and
149
* try again with a superclass or superinterface.
150
*/
151
if (!Modifier.isPublic(cls.getModifiers())) {
152
return false;
153
}
154
if (!ReflectUtil.isPackageAccessible(cls)) {
155
return false;
156
}
157
158
methods = cls.getMethods();
159
} catch (SecurityException se) {
160
return false;
161
}
162
163
/*
164
* Check for inherited methods with non-public
165
* declaring classes. They might override and hide
166
* methods from their superclasses or
167
* superinterfaces.
168
*/
169
boolean done = true;
170
for (int i=0; i < methods.length; i++) {
171
Class<?> dc = methods[i].getDeclaringClass();
172
if (!Modifier.isPublic(dc.getModifiers())) {
173
done = false;
174
break;
175
}
176
}
177
178
if (done) {
179
/*
180
* We're done. Spray all the methods into
181
* the list and then we're out of here.
182
*/
183
for (int i=0; i < methods.length; i++) {
184
addMethod(sigs, methods[i]);
185
}
186
} else {
187
/*
188
* Simulate cls.getDeclaredMethods() by
189
* stripping away inherited methods.
190
*/
191
for (int i=0; i < methods.length; i++) {
192
Class<?> dc = methods[i].getDeclaringClass();
193
if (cls.equals(dc)) {
194
addMethod(sigs, methods[i]);
195
}
196
}
197
}
198
return done;
199
}
200
201
private static void addMethod(Map<Signature, Method> sigs, Method method) {
202
Signature signature = new Signature(method);
203
if (!sigs.containsKey(signature)) {
204
sigs.put(signature, method);
205
} else if (!method.getDeclaringClass().isInterface()){
206
/*
207
* Superclasses beat interfaces.
208
*/
209
Method old = sigs.get(signature);
210
if (old.getDeclaringClass().isInterface()) {
211
sigs.put(signature, method);
212
}
213
}
214
}
215
216
/**
217
* A class that represents the unique elements of a method that will be a
218
* key in the method cache.
219
*/
220
private static class Signature {
221
private final String methodName;
222
private final Class<?>[] argClasses;
223
private final int hashCode;
224
225
Signature(Method m) {
226
this.methodName = m.getName();
227
this.argClasses = m.getParameterTypes();
228
this.hashCode = methodName.hashCode() + Arrays.hashCode(argClasses);
229
}
230
231
@Override public int hashCode() {
232
return hashCode;
233
}
234
235
@Override public boolean equals(Object o2) {
236
if (this == o2) {
237
return true;
238
}
239
Signature that = (Signature)o2;
240
if (!(methodName.equals(that.methodName))) {
241
return false;
242
}
243
if (argClasses.length != that.argClasses.length) {
244
return false;
245
}
246
for (int i = 0; i < argClasses.length; i++) {
247
if (!(argClasses[i] == that.argClasses[i])) {
248
return false;
249
}
250
}
251
return true;
252
}
253
}
254
255
256
/*
257
* Bounce through the trampoline.
258
*/
259
public static Object invoke(Method m, Object obj, Object[] params)
260
throws InvocationTargetException, IllegalAccessException {
261
try {
262
return bounce.invoke(null, new Object[] {m, obj, params});
263
} catch (InvocationTargetException ie) {
264
Throwable t = ie.getCause();
265
266
if (t instanceof InvocationTargetException) {
267
throw (InvocationTargetException)t;
268
} else if (t instanceof IllegalAccessException) {
269
throw (IllegalAccessException)t;
270
} else if (t instanceof RuntimeException) {
271
throw (RuntimeException)t;
272
} else if (t instanceof Error) {
273
throw (Error)t;
274
} else {
275
throw new Error("Unexpected invocation error", t);
276
}
277
} catch (IllegalAccessException iae) {
278
// this can't happen
279
throw new Error("Unexpected invocation error", iae);
280
}
281
}
282
283
@SuppressWarnings("removal")
284
private static Method getTrampoline() {
285
try {
286
return AccessController.doPrivileged(
287
new PrivilegedExceptionAction<Method>() {
288
public Method run() throws Exception {
289
Class<?> t = getTrampolineClass();
290
Class<?>[] types = {
291
Method.class, Object.class, Object[].class
292
};
293
Method b = t.getDeclaredMethod("invoke", types);
294
b.setAccessible(true);
295
return b;
296
}
297
});
298
} catch (Exception e) {
299
throw new InternalError("bouncer cannot be found", e);
300
}
301
}
302
303
304
protected synchronized Class<?> loadClass(String name, boolean resolve)
305
throws ClassNotFoundException
306
{
307
// First, check if the class has already been loaded
308
ReflectUtil.checkPackageAccess(name);
309
Class<?> c = findLoadedClass(name);
310
if (c == null) {
311
try {
312
c = findClass(name);
313
} catch (ClassNotFoundException e) {
314
// Fall through ...
315
}
316
if (c == null) {
317
c = getParent().loadClass(name);
318
}
319
}
320
if (resolve) {
321
resolveClass(c);
322
}
323
return c;
324
}
325
326
327
protected Class<?> findClass(final String name)
328
throws ClassNotFoundException
329
{
330
if (!name.startsWith(MISC_PKG)) {
331
throw new ClassNotFoundException(name);
332
}
333
String path = name.replace('.', '/').concat(".class");
334
try {
335
InputStream in = Object.class.getModule().getResourceAsStream(path);
336
if (in != null) {
337
try (in) {
338
byte[] b = in.readAllBytes();
339
return defineClass(name, b);
340
}
341
}
342
} catch (IOException e) {
343
throw new ClassNotFoundException(name, e);
344
}
345
346
throw new ClassNotFoundException(name);
347
}
348
349
350
/*
351
* Define the proxy classes
352
*/
353
private Class<?> defineClass(String name, byte[] b) throws IOException {
354
CodeSource cs = new CodeSource(null, (java.security.cert.Certificate[])null);
355
if (!name.equals(TRAMPOLINE)) {
356
throw new IOException("MethodUtil: bad name " + name);
357
}
358
return defineClass(name, b, 0, b.length, cs);
359
}
360
361
protected PermissionCollection getPermissions(CodeSource codesource)
362
{
363
PermissionCollection perms = super.getPermissions(codesource);
364
perms.add(new AllPermission());
365
return perms;
366
}
367
368
private static Class<?> getTrampolineClass() {
369
try {
370
return Class.forName(TRAMPOLINE, true, new MethodUtil());
371
} catch (ClassNotFoundException e) {
372
}
373
return null;
374
}
375
376
}
377
378