1 | /* |
2 | * Copyright (c) 1994, 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. 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 | /*- |
27 | * Implementation of class Class |
28 | * |
29 | * former threadruntime.c, Sun Sep 22 12:09:39 1991 |
30 | */ |
31 | |
32 | #include <string.h> |
33 | #include <stdlib.h> |
34 | |
35 | #include "jni.h" |
36 | #include "jni_util.h" |
37 | #include "jvm.h" |
38 | #include "java_lang_Class.h" |
39 | |
40 | /* defined in libverify.so/verify.dll (src file common/check_format.c) */ |
41 | extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed); |
42 | extern jboolean VerifyFixClassname(char *utf_name); |
43 | |
44 | #define OBJ "Ljava/lang/Object;" |
45 | #define CLS "Ljava/lang/Class;" |
46 | #define CPL "Ljdk/internal/reflect/ConstantPool;" |
47 | #define STR "Ljava/lang/String;" |
48 | #define FLD "Ljava/lang/reflect/Field;" |
49 | #define MHD "Ljava/lang/reflect/Method;" |
50 | #define CTR "Ljava/lang/reflect/Constructor;" |
51 | #define PD "Ljava/security/ProtectionDomain;" |
52 | #define BA "[B" |
53 | |
54 | static JNINativeMethod methods[] = { |
55 | {"initClassName" , "()" STR, (void *)&JVM_InitClassName}, |
56 | {"getSuperclass" , "()" CLS, NULL}, |
57 | {"getInterfaces0" , "()[" CLS, (void *)&JVM_GetClassInterfaces}, |
58 | {"isInterface" , "()Z" , (void *)&JVM_IsInterface}, |
59 | {"getSigners" , "()[" OBJ, (void *)&JVM_GetClassSigners}, |
60 | {"setSigners" , "([" OBJ ")V" , (void *)&JVM_SetClassSigners}, |
61 | {"isArray" , "()Z" , (void *)&JVM_IsArrayClass}, |
62 | {"isPrimitive" , "()Z" , (void *)&JVM_IsPrimitiveClass}, |
63 | {"getModifiers" , "()I" , (void *)&JVM_GetClassModifiers}, |
64 | {"getDeclaredFields0" ,"(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields}, |
65 | {"getDeclaredMethods0" ,"(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods}, |
66 | {"getDeclaredConstructors0" ,"(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors}, |
67 | {"getProtectionDomain0" , "()" PD, (void *)&JVM_GetProtectionDomain}, |
68 | {"getDeclaredClasses0" , "()[" CLS, (void *)&JVM_GetDeclaredClasses}, |
69 | {"getDeclaringClass0" , "()" CLS, (void *)&JVM_GetDeclaringClass}, |
70 | {"getSimpleBinaryName0" , "()" STR, (void *)&JVM_GetSimpleBinaryName}, |
71 | {"getGenericSignature0" , "()" STR, (void *)&JVM_GetClassSignature}, |
72 | {"getRawAnnotations" , "()" BA, (void *)&JVM_GetClassAnnotations}, |
73 | {"getConstantPool" , "()" CPL, (void *)&JVM_GetClassConstantPool}, |
74 | {"desiredAssertionStatus0" ,"(" CLS")Z" , (void *)&JVM_DesiredAssertionStatus}, |
75 | {"getEnclosingMethod0" , "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo}, |
76 | {"getRawTypeAnnotations" , "()" BA, (void *)&JVM_GetClassTypeAnnotations}, |
77 | {"getNestHost0" , "()" CLS, (void *)&JVM_GetNestHost}, |
78 | {"getNestMembers0" , "()[" CLS, (void *)&JVM_GetNestMembers}, |
79 | }; |
80 | |
81 | #undef OBJ |
82 | #undef CLS |
83 | #undef STR |
84 | #undef FLD |
85 | #undef MHD |
86 | #undef CTR |
87 | #undef PD |
88 | |
89 | JNIEXPORT void JNICALL |
90 | Java_java_lang_Class_registerNatives(JNIEnv *env, jclass cls) |
91 | { |
92 | methods[1].fnPtr = (void *)(*env)->GetSuperclass; |
93 | (*env)->RegisterNatives(env, cls, methods, |
94 | sizeof(methods)/sizeof(JNINativeMethod)); |
95 | } |
96 | |
97 | JNIEXPORT jclass JNICALL |
98 | Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname, |
99 | jboolean initialize, jobject loader, jclass caller) |
100 | { |
101 | char *clname; |
102 | jclass cls = 0; |
103 | char buf[128]; |
104 | jsize len; |
105 | jsize unicode_len; |
106 | |
107 | if (classname == NULL) { |
108 | JNU_ThrowNullPointerException(env, 0); |
109 | return 0; |
110 | } |
111 | |
112 | len = (*env)->GetStringUTFLength(env, classname); |
113 | unicode_len = (*env)->GetStringLength(env, classname); |
114 | if (len >= (jsize)sizeof(buf)) { |
115 | clname = malloc(len + 1); |
116 | if (clname == NULL) { |
117 | JNU_ThrowOutOfMemoryError(env, NULL); |
118 | return NULL; |
119 | } |
120 | } else { |
121 | clname = buf; |
122 | } |
123 | (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname); |
124 | |
125 | if (VerifyFixClassname(clname) == JNI_TRUE) { |
126 | /* slashes present in clname, use name b4 translation for exception */ |
127 | (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname); |
128 | JNU_ThrowClassNotFoundException(env, clname); |
129 | goto done; |
130 | } |
131 | |
132 | if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */ |
133 | JNU_ThrowClassNotFoundException(env, clname); |
134 | goto done; |
135 | } |
136 | |
137 | cls = JVM_FindClassFromCaller(env, clname, initialize, loader, caller); |
138 | |
139 | done: |
140 | if (clname != buf) { |
141 | free(clname); |
142 | } |
143 | return cls; |
144 | } |
145 | |
146 | JNIEXPORT jboolean JNICALL |
147 | Java_java_lang_Class_isInstance(JNIEnv *env, jobject cls, jobject obj) |
148 | { |
149 | if (obj == NULL) { |
150 | return JNI_FALSE; |
151 | } |
152 | return (*env)->IsInstanceOf(env, obj, (jclass)cls); |
153 | } |
154 | |
155 | JNIEXPORT jboolean JNICALL |
156 | Java_java_lang_Class_isAssignableFrom(JNIEnv *env, jobject cls, jobject cls2) |
157 | { |
158 | if (cls2 == NULL) { |
159 | JNU_ThrowNullPointerException(env, 0); |
160 | return JNI_FALSE; |
161 | } |
162 | return (*env)->IsAssignableFrom(env, cls2, cls); |
163 | } |
164 | |
165 | JNIEXPORT jclass JNICALL |
166 | Java_java_lang_Class_getPrimitiveClass(JNIEnv *env, |
167 | jclass cls, |
168 | jstring name) |
169 | { |
170 | const char *utfName; |
171 | jclass result; |
172 | |
173 | if (name == NULL) { |
174 | JNU_ThrowNullPointerException(env, 0); |
175 | return NULL; |
176 | } |
177 | |
178 | utfName = (*env)->GetStringUTFChars(env, name, 0); |
179 | if (utfName == 0) |
180 | return NULL; |
181 | |
182 | result = JVM_FindPrimitiveClass(env, utfName); |
183 | |
184 | (*env)->ReleaseStringUTFChars(env, name, utfName); |
185 | |
186 | return result; |
187 | } |
188 | |