blob: 4bc1caa08d67e3a716f9f8b9122786a8742de736 [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) {
38 Class* c = Decode<Class*>(env, javaThis);
39 if (!c->IsArrayClass()) {
40 return NULL;
41 }
42
43 /*
44 * We can't just return c->GetComponentType(), because that gives
45 * us the base type (e.g. X[][][] returns X). If this is a multi-
46 * dimensional array, we have to do the lookup by name.
47 */
48 Class* result;
49 std::string descriptor(c->GetDescriptor()->ToModifiedUtf8());
50 if (descriptor[1] == '[') {
51 result = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str() + 1, c->GetClassLoader());
52 } else {
53 result = c->GetComponentType();
54 }
55 return AddLocalReference<jclass>(env, result);
Elliott Hughesd369bb72011-09-12 14:41:14 -070056}
57
58jobjectArray Class_getDeclaredClasses(JNIEnv* env, jclass java_lang_Class_class, jclass c, jboolean publicOnly) {
Elliott Hughes6bdc3b22011-09-16 19:24:10 -070059 UNIMPLEMENTED(WARNING) << "needs annotations";
Elliott Hughesd369bb72011-09-12 14:41:14 -070060 return env->NewObjectArray(0, java_lang_Class_class, NULL);
61}
62
Brian Carlstromf867b6f2011-09-16 12:17:25 -070063jobject Class_getDeclaredField(JNIEnv* env, jclass java_lang_Class_class, jclass jklass, jobject jname) {
64 Class* klass = Decode<Class*>(env, jklass);
65 DCHECK(klass->IsClass());
66 String* name = Decode<String*>(env, jname);
67 DCHECK(name->IsString());
68
69 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
70 Field* f = klass->GetInstanceField(i);
71 if (f->GetName()->Equals(name)) {
72 return AddLocalReference<jclass>(env, f);
73 }
74 }
75 for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
76 Field* f = klass->GetStaticField(i);
77 if (f->GetName()->Equals(name)) {
78 return AddLocalReference<jclass>(env, f);
79 }
80 }
81 return NULL;
82}
83
Elliott Hughes6bdc3b22011-09-16 19:24:10 -070084jclass Class_getDeclaringClass(JNIEnv* env, jobject javaThis) {
85 UNIMPLEMENTED(WARNING) << "needs annotations";
86 return NULL;
87}
88
89jobject Class_getEnclosingConstructor(JNIEnv* env, jobject javaThis) {
90 UNIMPLEMENTED(WARNING) << "needs annotations";
91 return NULL;
92}
93
94jobject Class_getEnclosingMethod(JNIEnv* env, jobject javaThis) {
95 UNIMPLEMENTED(WARNING) << "needs annotations";
96 return NULL;
97}
98
99/*
100 * private native String getNameNative()
101 *
102 * Return the class' name. The exact format is bizarre, but it's the specified
103 * behavior: keywords for primitive types, regular "[I" form for primitive
104 * arrays (so "int" but "[I"), and arrays of reference types written
105 * between "L" and ";" but with dots rather than slashes (so "java.lang.String"
106 * but "[Ljava.lang.String;"). Madness.
107 */
108jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
109 Class* c = Decode<Class*>(env, javaThis);
110 std::string descriptor(c->GetDescriptor()->ToModifiedUtf8());
111 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
112 // The descriptor indicates that this is the class for
113 // a primitive type; special-case the return value.
114 const char* name = NULL;
115 switch (descriptor[0]) {
116 case 'Z': name = "boolean"; break;
117 case 'B': name = "byte"; break;
118 case 'C': name = "char"; break;
119 case 'S': name = "short"; break;
120 case 'I': name = "int"; break;
121 case 'J': name = "long"; break;
122 case 'F': name = "float"; break;
123 case 'D': name = "double"; break;
124 case 'V': name = "void"; break;
125 default:
126 LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
127 }
128 return env->NewStringUTF(name);
129 }
130
131 // Convert the UTF-8 name to a java.lang.String. The
132 // name must use '.' to separate package components.
133 if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') {
134 descriptor.erase(0, 1);
135 descriptor.erase(descriptor.size() - 1);
136 }
137 std::replace(descriptor.begin(), descriptor.end(), '/', '.');
138 return env->NewStringUTF(descriptor.c_str());
139}
140
141jclass Class_getSuperclass(JNIEnv* env, jobject javaThis) {
142 Class* c = Decode<Class*>(env, javaThis);
143 Class* result = c->GetSuperClass();
144 return AddLocalReference<jclass>(env, result);
145}
146
147jboolean Class_isAnonymousClass(JNIEnv* env, jobject javaThis) {
148 UNIMPLEMENTED(WARNING) << "needs annotations";
149 return JNI_FALSE;
150}
151
152jboolean Class_isInterface(JNIEnv* env, jobject javaThis) {
153 Class* c = Decode<Class*>(env, javaThis);
154 return c->IsInterface();
155}
156
157jboolean Class_isPrimitive(JNIEnv* env, jobject javaThis) {
158 Class* c = Decode<Class*>(env, javaThis);
159 return c->IsPrimitive();
160}
161
Elliott Hughesd369bb72011-09-12 14:41:14 -0700162static JNINativeMethod gMethods[] = {
163 //NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700164 NATIVE_METHOD(Class, desiredAssertionStatus, "()Z"),
165 NATIVE_METHOD(Class, getClassLoader, "(Ljava/lang/Class;)Ljava/lang/ClassLoader;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700166 NATIVE_METHOD(Class, getComponentType, "()Ljava/lang/Class;"),
167 //NATIVE_METHOD(Class, getDeclaredAnnotation, "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
168 //NATIVE_METHOD(Class, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),
169 NATIVE_METHOD(Class, getDeclaredClasses, "(Ljava/lang/Class;Z)[Ljava/lang/Class;"),
170 //NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"),
171 //NATIVE_METHOD(Class, getDeclaredConstructors, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;"),
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700172 NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700173 //NATIVE_METHOD(Class, getDeclaredFields, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;"),
174 //NATIVE_METHOD(Class, getDeclaredMethods, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700175 NATIVE_METHOD(Class, getDeclaringClass, "()Ljava/lang/Class;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700176 //NATIVE_METHOD(Class, getEnclosingClass, "()Ljava/lang/Class;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700177 NATIVE_METHOD(Class, getEnclosingConstructor, "()Ljava/lang/reflect/Constructor;"),
178 NATIVE_METHOD(Class, getEnclosingMethod, "()Ljava/lang/reflect/Method;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700179 //NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"),
180 //NATIVE_METHOD(Class, getInterfaces, "()[Ljava/lang/Class;"),
181 //NATIVE_METHOD(Class, getModifiers, "(Ljava/lang/Class;Z)I"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700182 NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700183 //NATIVE_METHOD(Class, getSignatureAnnotation, "()[Ljava/lang/Object;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700184 NATIVE_METHOD(Class, getSuperclass, "()Ljava/lang/Class;"),
185 NATIVE_METHOD(Class, isAnonymousClass, "()Z"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700186 //NATIVE_METHOD(Class, isAssignableFrom, "(Ljava/lang/Class;)Z"),
187 //NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "(Ljava/lang/Class;)Z"),
188 //NATIVE_METHOD(Class, isInstance, "(Ljava/lang/Object;)Z"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700189 NATIVE_METHOD(Class, isInterface, "()Z"),
190 NATIVE_METHOD(Class, isPrimitive, "()Z"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700191 //NATIVE_METHOD(Class, newInstanceImpl, "()Ljava/lang/Object;"),
192};
193
194} // namespace
195
196void register_java_lang_Class(JNIEnv* env) {
197 jniRegisterNativeMethods(env, "java/lang/Class", gMethods, NELEM(gMethods));
198}
199
200} // namespace art