blob: 8ad59b4566f83ae2bdfc1e98da70b6adca683cf9 [file] [log] [blame]
Elliott Hughesd369bb72011-09-12 14:41:14 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "jni_internal.h"
18#include "class_linker.h"
19#include "object.h"
20
21#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
22
23namespace art {
24
25namespace {
26
Elliott Hughes6bdc3b22011-09-16 19:24:10 -070027jboolean Class_desiredAssertionStatus(JNIEnv* env, jobject javaThis) {
28 return JNI_FALSE;
29}
30
31jobject Class_getClassLoader(JNIEnv* env, jclass, jobject javaClass) {
32 Class* c = Decode<Class*>(env, javaClass);
33 Object* result = reinterpret_cast<Object*>(const_cast<ClassLoader*>(c->GetClassLoader()));
34 return AddLocalReference<jobject>(env, result);
35}
36
Elliott Hughesd369bb72011-09-12 14:41:14 -070037jclass Class_getComponentType(JNIEnv* env, jobject javaThis) {
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -070038 return AddLocalReference<jclass>(env, Decode<Class*>(env, javaThis)->GetComponentType());
Elliott Hughesd369bb72011-09-12 14:41:14 -070039}
40
41jobjectArray Class_getDeclaredClasses(JNIEnv* env, jclass java_lang_Class_class, jclass c, jboolean publicOnly) {
Elliott Hughes6bdc3b22011-09-16 19:24:10 -070042 UNIMPLEMENTED(WARNING) << "needs annotations";
Elliott Hughesd369bb72011-09-12 14:41:14 -070043 return env->NewObjectArray(0, java_lang_Class_class, NULL);
44}
45
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -070046jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass,
47 jclass jklass, jstring jname, jobjectArray jsignature) {
48 Class* klass = Decode<Class*>(env, jklass);
49 DCHECK(klass->IsClass());
50 String* name = Decode<String*>(env, jname);
51 DCHECK(name->IsString());
52 Object* signature_obj = Decode<Object*>(env, jsignature);
53 DCHECK(signature_obj->IsArrayInstance());
Brian Carlstrom03c99df2011-09-18 10:52:00 -070054 // check that this is a Class[] by checking that component type is Class
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -070055 // foo->GetClass()->GetClass() is an idiom for getting java.lang.Class from an arbitrary object
56 DCHECK(signature_obj->GetClass()->GetComponentType() == signature_obj->GetClass()->GetClass());
57 ObjectArray<Class>* signature = down_cast<ObjectArray<Class>*>(signature_obj);
58
59 std::string name_string = name->ToModifiedUtf8();
60 std::string signature_string;
61 signature_string += "(";
62 for (int i = 0; i < signature->GetLength(); i++) {
63 Class* argument_class = signature->Get(0);
64 if (argument_class == NULL) {
65 UNIMPLEMENTED(FATAL) << "throw null pointer exception?";
66 }
67 signature_string += argument_class->GetDescriptor()->ToModifiedUtf8();
68 }
69 signature_string += ")";
70
71 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
72 Method* method = klass->GetVirtualMethod(i);
73 if (!method->GetName()->Equals(name)) {
74 continue;
75 }
76 std::string method_signature = method->GetSignature()->ToModifiedUtf8();
77 if (!StringPiece(method_signature).starts_with(signature_string)) {
78 continue;
79 }
80 return AddLocalReference<jobject>(env, method);
81 }
82
Brian Carlstrom03c99df2011-09-18 10:52:00 -070083 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
84 Method* method = klass->GetDirectMethod(i);
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -070085 if (!method->GetName()->Equals(name)) {
86 continue;
87 }
88 std::string method_signature = method->GetSignature()->ToModifiedUtf8();
89 if (!StringPiece(method_signature).starts_with(signature_string)) {
90 continue;
91 }
92 return AddLocalReference<jobject>(env, method);
93 }
94
95 return NULL;
96}
97
98jobject Class_getDeclaredField(JNIEnv* env, jclass, jclass jklass, jobject jname) {
Brian Carlstromf867b6f2011-09-16 12:17:25 -070099 Class* klass = Decode<Class*>(env, jklass);
100 DCHECK(klass->IsClass());
101 String* name = Decode<String*>(env, jname);
102 DCHECK(name->IsString());
103
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700104 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700105 Field* f = klass->GetInstanceField(i);
106 if (f->GetName()->Equals(name)) {
107 return AddLocalReference<jclass>(env, f);
108 }
109 }
110 for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
111 Field* f = klass->GetStaticField(i);
112 if (f->GetName()->Equals(name)) {
113 return AddLocalReference<jclass>(env, f);
114 }
115 }
116 return NULL;
117}
118
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700119jclass Class_getDeclaringClass(JNIEnv* env, jobject javaThis) {
120 UNIMPLEMENTED(WARNING) << "needs annotations";
121 return NULL;
122}
123
124jobject Class_getEnclosingConstructor(JNIEnv* env, jobject javaThis) {
125 UNIMPLEMENTED(WARNING) << "needs annotations";
126 return NULL;
127}
128
129jobject Class_getEnclosingMethod(JNIEnv* env, jobject javaThis) {
130 UNIMPLEMENTED(WARNING) << "needs annotations";
131 return NULL;
132}
133
134/*
135 * private native String getNameNative()
136 *
137 * Return the class' name. The exact format is bizarre, but it's the specified
138 * behavior: keywords for primitive types, regular "[I" form for primitive
139 * arrays (so "int" but "[I"), and arrays of reference types written
140 * between "L" and ";" but with dots rather than slashes (so "java.lang.String"
141 * but "[Ljava.lang.String;"). Madness.
142 */
143jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
144 Class* c = Decode<Class*>(env, javaThis);
145 std::string descriptor(c->GetDescriptor()->ToModifiedUtf8());
146 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
147 // The descriptor indicates that this is the class for
148 // a primitive type; special-case the return value.
149 const char* name = NULL;
150 switch (descriptor[0]) {
151 case 'Z': name = "boolean"; break;
152 case 'B': name = "byte"; break;
153 case 'C': name = "char"; break;
154 case 'S': name = "short"; break;
155 case 'I': name = "int"; break;
156 case 'J': name = "long"; break;
157 case 'F': name = "float"; break;
158 case 'D': name = "double"; break;
159 case 'V': name = "void"; break;
160 default:
161 LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
162 }
163 return env->NewStringUTF(name);
164 }
165
166 // Convert the UTF-8 name to a java.lang.String. The
167 // name must use '.' to separate package components.
168 if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') {
169 descriptor.erase(0, 1);
170 descriptor.erase(descriptor.size() - 1);
171 }
172 std::replace(descriptor.begin(), descriptor.end(), '/', '.');
173 return env->NewStringUTF(descriptor.c_str());
174}
175
176jclass Class_getSuperclass(JNIEnv* env, jobject javaThis) {
177 Class* c = Decode<Class*>(env, javaThis);
178 Class* result = c->GetSuperClass();
179 return AddLocalReference<jclass>(env, result);
180}
181
182jboolean Class_isAnonymousClass(JNIEnv* env, jobject javaThis) {
183 UNIMPLEMENTED(WARNING) << "needs annotations";
184 return JNI_FALSE;
185}
186
187jboolean Class_isInterface(JNIEnv* env, jobject javaThis) {
188 Class* c = Decode<Class*>(env, javaThis);
189 return c->IsInterface();
190}
191
192jboolean Class_isPrimitive(JNIEnv* env, jobject javaThis) {
193 Class* c = Decode<Class*>(env, javaThis);
194 return c->IsPrimitive();
195}
196
Elliott Hughesd369bb72011-09-12 14:41:14 -0700197static JNINativeMethod gMethods[] = {
198 //NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700199 NATIVE_METHOD(Class, desiredAssertionStatus, "()Z"),
200 NATIVE_METHOD(Class, getClassLoader, "(Ljava/lang/Class;)Ljava/lang/ClassLoader;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700201 NATIVE_METHOD(Class, getComponentType, "()Ljava/lang/Class;"),
202 //NATIVE_METHOD(Class, getDeclaredAnnotation, "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
203 //NATIVE_METHOD(Class, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),
204 NATIVE_METHOD(Class, getDeclaredClasses, "(Ljava/lang/Class;Z)[Ljava/lang/Class;"),
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700205 NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700206 //NATIVE_METHOD(Class, getDeclaredConstructors, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;"),
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700207 NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700208 //NATIVE_METHOD(Class, getDeclaredFields, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;"),
209 //NATIVE_METHOD(Class, getDeclaredMethods, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700210 NATIVE_METHOD(Class, getDeclaringClass, "()Ljava/lang/Class;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700211 //NATIVE_METHOD(Class, getEnclosingClass, "()Ljava/lang/Class;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700212 NATIVE_METHOD(Class, getEnclosingConstructor, "()Ljava/lang/reflect/Constructor;"),
213 NATIVE_METHOD(Class, getEnclosingMethod, "()Ljava/lang/reflect/Method;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700214 //NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"),
215 //NATIVE_METHOD(Class, getInterfaces, "()[Ljava/lang/Class;"),
216 //NATIVE_METHOD(Class, getModifiers, "(Ljava/lang/Class;Z)I"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700217 NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700218 //NATIVE_METHOD(Class, getSignatureAnnotation, "()[Ljava/lang/Object;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700219 NATIVE_METHOD(Class, getSuperclass, "()Ljava/lang/Class;"),
220 NATIVE_METHOD(Class, isAnonymousClass, "()Z"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700221 //NATIVE_METHOD(Class, isAssignableFrom, "(Ljava/lang/Class;)Z"),
222 //NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "(Ljava/lang/Class;)Z"),
223 //NATIVE_METHOD(Class, isInstance, "(Ljava/lang/Object;)Z"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700224 NATIVE_METHOD(Class, isInterface, "()Z"),
225 NATIVE_METHOD(Class, isPrimitive, "()Z"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700226 //NATIVE_METHOD(Class, newInstanceImpl, "()Ljava/lang/Object;"),
227};
228
229} // namespace
230
231void register_java_lang_Class(JNIEnv* env) {
232 jniRegisterNativeMethods(env, "java/lang/Class", gMethods, NELEM(gMethods));
233}
234
235} // namespace art