blob: b85969e702c9c97959c72412cd6c71079f34c973 [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"
Brian Carlstromf91c8c32011-09-21 17:30:34 -070019#include "class_loader.h"
Elliott Hughesd369bb72011-09-12 14:41:14 -070020#include "object.h"
Elliott Hughes80609252011-09-23 17:24:51 -070021#include "ScopedLocalRef.h"
Brian Carlstromf91c8c32011-09-21 17:30:34 -070022#include "ScopedUtfChars.h"
Elliott Hughesd369bb72011-09-12 14:41:14 -070023
24#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
25
26namespace art {
27
28namespace {
29
Brian Carlstromf91c8c32011-09-21 17:30:34 -070030// "name" is in "binary name" format, e.g. "dalvik.system.Debug$1".
31jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize, jobject javaLoader) {
Brian Carlstromb82b6872011-10-26 17:18:07 -070032 ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
Brian Carlstromf91c8c32011-09-21 17:30:34 -070033 ScopedUtfChars name(env, javaName);
34 if (name.c_str() == NULL) {
35 return NULL;
36 }
37
38 // We need to validate and convert the name (from x.y.z to x/y/z). This
39 // is especially handy for array types, since we want to avoid
40 // auto-generating bogus array classes.
Elliott Hughes906e6852011-10-28 14:52:10 -070041 if (!IsValidBinaryClassName(name.c_str())) {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -070042 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ClassNotFoundException;",
Brian Carlstromf91c8c32011-09-21 17:30:34 -070043 "Invalid name: %s", name.c_str());
44 return NULL;
45 }
46
47 std::string descriptor(DotToDescriptor(name.c_str()));
48 Object* loader = Decode<Object*>(env, javaLoader);
49 ClassLoader* class_loader = down_cast<ClassLoader*>(loader);
50 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
51 Class* c = class_linker->FindClass(descriptor.c_str(), class_loader);
Brian Carlstrom395520e2011-09-25 19:35:00 -070052 if (c == NULL) {
53 // Convert NoClassDefFoundError to ClassNotFoundException
54 // TODO: chain exceptions?
55 DCHECK(env->ExceptionCheck());
56 env->ExceptionClear();
Elliott Hughes5cb5ad22011-10-02 12:13:39 -070057 Thread::Current()->ThrowNewException("Ljava/lang/ClassNotFoundException;", name.c_str());
Brian Carlstrom395520e2011-09-25 19:35:00 -070058 return NULL;
59 }
Brian Carlstromf91c8c32011-09-21 17:30:34 -070060 if (initialize) {
61 class_linker->EnsureInitialized(c, true);
62 }
63 return AddLocalReference<jclass>(env, c);
64}
65
Elliott Hughes80609252011-09-23 17:24:51 -070066template<typename T>
67jobjectArray ToArray(JNIEnv* env, const char* array_class_name, const std::vector<T*>& objects) {
68 jclass array_class = env->FindClass(array_class_name);
69 jobjectArray result = env->NewObjectArray(objects.size(), array_class, NULL);
70 for (size_t i = 0; i < objects.size(); ++i) {
71 ScopedLocalRef<jobject> object(env, AddLocalReference<jobject>(env, objects[i]));
72 env->SetObjectArrayElement(result, i, object.get());
73 }
74 return result;
75}
76
77bool IsVisibleConstructor(Method* m, bool public_only) {
78 if (public_only && !m->IsPublic()) {
79 return false;
80 }
Ian Rogers9074b992011-10-26 17:41:55 -070081 if (m->IsStatic()) {
Elliott Hughes80609252011-09-23 17:24:51 -070082 return false;
83 }
84 if (m->GetName()->CharAt(0) != '<') {
85 return false;
86 }
87 m->InitJavaFields();
88 return true;
89}
90
91jobjectArray Class_getDeclaredConstructors(JNIEnv* env, jclass, jclass javaClass, jboolean publicOnly) {
92 Class* c = Decode<Class*>(env, javaClass);
93
94 std::vector<Method*> constructors;
95 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
96 Method* m = c->GetDirectMethod(i);
97 if (IsVisibleConstructor(m, publicOnly)) {
98 constructors.push_back(m);
99 }
100 }
101
102 return ToArray(env, "java/lang/reflect/Constructor", constructors);
103}
104
105bool IsVisibleField(Field* f, bool public_only) {
Elliott Hughesc0dd3122011-09-26 10:15:43 -0700106 if (public_only && !f->IsPublic()) {
Elliott Hughes80609252011-09-23 17:24:51 -0700107 return false;
108 }
109 f->InitJavaFields();
110 return true;
111}
112
113jobjectArray Class_getDeclaredFields(JNIEnv* env, jclass, jclass javaClass, jboolean publicOnly) {
114 Class* c = Decode<Class*>(env, javaClass);
115
116 std::vector<Field*> fields;
117 for (size_t i = 0; i < c->NumInstanceFields(); ++i) {
118 Field* f = c->GetInstanceField(i);
119 if (IsVisibleField(f, publicOnly)) {
120 fields.push_back(f);
121 }
Jesse Wilson53494312011-11-29 16:43:09 -0500122 if (env->ExceptionOccurred()) {
123 return NULL;
124 }
Elliott Hughes80609252011-09-23 17:24:51 -0700125 }
126 for (size_t i = 0; i < c->NumStaticFields(); ++i) {
127 Field* f = c->GetStaticField(i);
128 if (IsVisibleField(f, publicOnly)) {
129 fields.push_back(f);
130 }
Jesse Wilson53494312011-11-29 16:43:09 -0500131 if (env->ExceptionOccurred()) {
132 return NULL;
133 }
Elliott Hughes80609252011-09-23 17:24:51 -0700134 }
135
136 return ToArray(env, "java/lang/reflect/Field", fields);
137}
138
139bool IsVisibleMethod(Method* m, bool public_only) {
140 if (public_only && !m->IsPublic()) {
141 return false;
142 }
Elliott Hughes80609252011-09-23 17:24:51 -0700143 if (m->GetName()->CharAt(0) == '<') {
144 return false;
145 }
146 m->InitJavaFields();
147 return true;
148}
149
150jobjectArray Class_getDeclaredMethods(JNIEnv* env, jclass, jclass javaClass, jboolean publicOnly) {
151 Class* c = Decode<Class*>(env, javaClass);
152
153 std::vector<Method*> methods;
154 for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
155 Method* m = c->GetVirtualMethod(i);
156 if (IsVisibleMethod(m, publicOnly)) {
157 methods.push_back(m);
158 }
Jesse Wilson53494312011-11-29 16:43:09 -0500159 if (env->ExceptionOccurred()) {
160 return NULL;
161 }
Elliott Hughes80609252011-09-23 17:24:51 -0700162 }
163 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
164 Method* m = c->GetDirectMethod(i);
165 if (IsVisibleMethod(m, publicOnly)) {
166 methods.push_back(m);
167 }
Jesse Wilson53494312011-11-29 16:43:09 -0500168 if (env->ExceptionOccurred()) {
169 return NULL;
170 }
Elliott Hughes80609252011-09-23 17:24:51 -0700171 }
172
173 return ToArray(env, "java/lang/reflect/Method", methods);
174}
175
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700176jboolean Class_desiredAssertionStatus(JNIEnv* env, jobject javaThis) {
177 return JNI_FALSE;
178}
179
Jesse Wilson6bf19152011-09-29 13:12:33 -0400180jobject Class_getDex(JNIEnv* env, jobject javaClass) {
181 Class* c = Decode<Class*>(env, javaClass);
182
183 DexCache* dex_cache = c->GetDexCache();
184 if (dex_cache == NULL) {
185 return NULL;
186 }
187
188 return Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache).GetDexObject(env);
189}
190
Jesse Wilson163c4642011-10-12 10:42:15 -0400191jint Class_getNonInnerClassModifiers(JNIEnv* env, jclass, jclass javaClass) {
Elliott Hughes9dcc79d2011-10-02 16:31:10 -0700192 Class* c = Decode<Class*>(env, javaClass);
Jesse Wilson163c4642011-10-12 10:42:15 -0400193 return c->GetAccessFlags() & kAccJavaFlagsMask;
Elliott Hughes9dcc79d2011-10-02 16:31:10 -0700194}
195
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700196jobject Class_getClassLoader(JNIEnv* env, jclass, jobject javaClass) {
197 Class* c = Decode<Class*>(env, javaClass);
Elliott Hughes1bba14f2011-12-01 18:00:36 -0800198 Object* result = c->GetClassLoader();
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700199 return AddLocalReference<jobject>(env, result);
200}
201
Elliott Hughesd369bb72011-09-12 14:41:14 -0700202jclass Class_getComponentType(JNIEnv* env, jobject javaThis) {
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700203 return AddLocalReference<jclass>(env, Decode<Class*>(env, javaThis)->GetComponentType());
Elliott Hughesd369bb72011-09-12 14:41:14 -0700204}
205
Elliott Hughes418d20f2011-09-22 14:00:39 -0700206bool MethodMatches(Method* m, String* name, const std::string& signature) {
207 if (!m->GetName()->Equals(name)) {
208 return false;
209 }
210 std::string method_signature = m->GetSignature()->ToModifiedUtf8();
211 if (!StringPiece(method_signature).starts_with(signature)) {
212 return false;
213 }
Jesse Wilson8ea36f82011-11-21 10:35:06 -0500214 if (m->IsMiranda()) {
215 return false;
216 }
Elliott Hughes418d20f2011-09-22 14:00:39 -0700217 return true;
218}
219
Jesse Wilson8ea36f82011-11-21 10:35:06 -0500220Method* FindConstructorOrMethodInArray(ObjectArray<Method>* methods, String* name,
Jesse Wilson50e537e2011-11-29 16:53:29 -0500221 const std::string& signature) {
Jesse Wilson8ea36f82011-11-21 10:35:06 -0500222 if (methods == NULL) {
223 return NULL;
224 }
225 Method* result = NULL;
226 for (int32_t i = 0; i < methods->GetLength(); ++i) {
227 Method* method = methods->Get(i);
228 if (!MethodMatches(method, name, signature)) {
229 continue;
230 }
231
232 result = method;
233
234 // Covariant return types permit the class to define multiple
235 // methods with the same name and parameter types. Prefer to return
236 // a non-synthetic method in such situations. We may still return
237 // a synthetic method to handle situations like escalated visibility.
238 if (!method->IsSynthetic()) {
239 break;
240 }
241 }
242 return result;
243}
244
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700245jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass,
Elliott Hughes418d20f2011-09-22 14:00:39 -0700246 jclass javaClass, jstring javaName, jobjectArray javaSignature) {
247 Class* c = Decode<Class*>(env, javaClass);
248 String* name = Decode<String*>(env, javaName);
249 ObjectArray<Class>* signature_array = Decode<ObjectArray<Class>*>(env, javaSignature);
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700250
Elliott Hughes418d20f2011-09-22 14:00:39 -0700251 std::string signature;
252 signature += "(";
253 for (int i = 0; i < signature_array->GetLength(); i++) {
254 signature += signature_array->Get(i)->GetDescriptor()->ToModifiedUtf8();
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700255 }
Elliott Hughes418d20f2011-09-22 14:00:39 -0700256 signature += ")";
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700257
Jesse Wilson8ea36f82011-11-21 10:35:06 -0500258 Method* m = FindConstructorOrMethodInArray(c->GetDirectMethods(), name, signature);
259 if (m == NULL) {
260 m = FindConstructorOrMethodInArray(c->GetVirtualMethods(), name, signature);
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700261 }
262
Jesse Wilson8ea36f82011-11-21 10:35:06 -0500263 if (m != NULL) {
264 m->InitJavaFields();
265 return AddLocalReference<jobject>(env, m);
266 } else {
267 return NULL;
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700268 }
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700269}
270
271jobject Class_getDeclaredField(JNIEnv* env, jclass, jclass jklass, jobject jname) {
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700272 Class* klass = Decode<Class*>(env, jklass);
273 DCHECK(klass->IsClass());
274 String* name = Decode<String*>(env, jname);
Elliott Hughesdbb40792011-11-18 17:05:22 -0800275 DCHECK(name->GetClass()->IsStringClass());
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700276
Elliott Hughes80609252011-09-23 17:24:51 -0700277 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700278 Field* f = klass->GetInstanceField(i);
279 if (f->GetName()->Equals(name)) {
Elliott Hughes80609252011-09-23 17:24:51 -0700280 f->InitJavaFields();
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700281 return AddLocalReference<jclass>(env, f);
282 }
283 }
284 for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
285 Field* f = klass->GetStaticField(i);
286 if (f->GetName()->Equals(name)) {
Elliott Hughes80609252011-09-23 17:24:51 -0700287 f->InitJavaFields();
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700288 return AddLocalReference<jclass>(env, f);
289 }
290 }
291 return NULL;
292}
293
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700294/*
295 * private native String getNameNative()
296 *
297 * Return the class' name. The exact format is bizarre, but it's the specified
298 * behavior: keywords for primitive types, regular "[I" form for primitive
299 * arrays (so "int" but "[I"), and arrays of reference types written
300 * between "L" and ";" but with dots rather than slashes (so "java.lang.String"
301 * but "[Ljava.lang.String;"). Madness.
302 */
303jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
304 Class* c = Decode<Class*>(env, javaThis);
305 std::string descriptor(c->GetDescriptor()->ToModifiedUtf8());
306 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
307 // The descriptor indicates that this is the class for
308 // a primitive type; special-case the return value.
309 const char* name = NULL;
310 switch (descriptor[0]) {
311 case 'Z': name = "boolean"; break;
312 case 'B': name = "byte"; break;
313 case 'C': name = "char"; break;
314 case 'S': name = "short"; break;
315 case 'I': name = "int"; break;
316 case 'J': name = "long"; break;
317 case 'F': name = "float"; break;
318 case 'D': name = "double"; break;
319 case 'V': name = "void"; break;
320 default:
321 LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
322 }
323 return env->NewStringUTF(name);
324 }
325
326 // Convert the UTF-8 name to a java.lang.String. The
327 // name must use '.' to separate package components.
328 if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') {
329 descriptor.erase(0, 1);
330 descriptor.erase(descriptor.size() - 1);
331 }
332 std::replace(descriptor.begin(), descriptor.end(), '/', '.');
333 return env->NewStringUTF(descriptor.c_str());
334}
335
336jclass Class_getSuperclass(JNIEnv* env, jobject javaThis) {
337 Class* c = Decode<Class*>(env, javaThis);
338 Class* result = c->GetSuperClass();
339 return AddLocalReference<jclass>(env, result);
340}
341
Elliott Hughesdd8df692011-09-23 14:42:41 -0700342jboolean Class_isAssignableFrom(JNIEnv* env, jobject javaLhs, jclass javaRhs) {
Brian Carlstromb82b6872011-10-26 17:18:07 -0700343 ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
Elliott Hughesdd8df692011-09-23 14:42:41 -0700344 Class* lhs = Decode<Class*>(env, javaLhs);
345 Class* rhs = Decode<Class*>(env, javaRhs);
346 if (rhs == NULL) {
347 Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", "class == null");
348 return JNI_FALSE;
349 }
350 return lhs->IsAssignableFrom(rhs) ? JNI_TRUE : JNI_FALSE;
351}
352
353jboolean Class_isInstance(JNIEnv* env, jobject javaClass, jobject javaObject) {
354 Class* c = Decode<Class*>(env, javaClass);
355 Object* o = Decode<Object*>(env, javaObject);
356 if (o == NULL) {
357 return JNI_FALSE;
358 }
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700359 return o->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughesdd8df692011-09-23 14:42:41 -0700360}
361
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700362jboolean Class_isInterface(JNIEnv* env, jobject javaThis) {
363 Class* c = Decode<Class*>(env, javaThis);
364 return c->IsInterface();
365}
366
367jboolean Class_isPrimitive(JNIEnv* env, jobject javaThis) {
368 Class* c = Decode<Class*>(env, javaThis);
369 return c->IsPrimitive();
370}
371
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700372// Validate method/field access.
373bool CheckMemberAccess(const Class* access_from, const Class* access_to, uint32_t member_flags) {
374 // quick accept for public access */
375 if (member_flags & kAccPublic) {
376 return true;
377 }
378
379 // quick accept for access from same class
380 if (access_from == access_to) {
381 return true;
382 }
383
384 // quick reject for private access from another class
385 if (member_flags & kAccPrivate) {
386 return false;
387 }
388
389 // Semi-quick test for protected access from a sub-class, which may or
390 // may not be in the same package.
391 if (member_flags & kAccProtected) {
392 if (access_from->IsSubClass(access_to)) {
393 return true;
394 }
395 }
396
397 // Allow protected and private access from other classes in the same
398 return access_from->IsInSamePackage(access_to);
399}
400
401jobject Class_newInstanceImpl(JNIEnv* env, jobject javaThis) {
Brian Carlstromb82b6872011-10-26 17:18:07 -0700402 ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700403 Class* c = Decode<Class*>(env, javaThis);
404 if (c->IsPrimitive() || c->IsInterface() || c->IsArrayClass() || c->IsAbstract()) {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -0700405 Thread::Current()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700406 "Class %s can not be instantiated", PrettyDescriptor(c->GetDescriptor()).c_str());
407 return NULL;
408 }
409
Elliott Hughes2a20cfd2011-09-23 19:30:41 -0700410 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true)) {
411 return NULL;
412 }
413
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700414 Method* init = c->FindDirectMethod("<init>", "()V");
415 if (init == NULL) {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -0700416 Thread::Current()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700417 "Class %s has no default <init>()V constructor", PrettyDescriptor(c->GetDescriptor()).c_str());
418 return NULL;
419 }
420
421 // Verify access from the call site.
422 //
423 // First, make sure the method invoking Class.newInstance() has permission
424 // to access the class.
425 //
426 // Second, make sure it has permission to invoke the constructor. The
427 // constructor must be public or, if the caller is in the same package,
428 // have package scope.
429 // TODO: need SmartFrame (Thread::WalkStack-like iterator).
430 Frame frame = Thread::Current()->GetTopOfStack();
431 frame.Next();
432 frame.Next();
433 Method* caller_caller = frame.GetMethod();
434 Class* caller_class = caller_caller->GetDeclaringClass();
435
Brian Carlstrombc2f3e32011-09-22 17:16:54 -0700436 if (!caller_class->CanAccess(c)) {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -0700437 Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalAccessException;",
438 "Class %s is not accessible from class %s",
439 PrettyDescriptor(c->GetDescriptor()).c_str(),
440 PrettyDescriptor(caller_class->GetDescriptor()).c_str());
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700441 return NULL;
442 }
443 if (!CheckMemberAccess(caller_class, init->GetDeclaringClass(), init->GetAccessFlags())) {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -0700444 Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalAccessException;",
445 "%s is not accessible from class %s",
446 PrettyMethod(init).c_str(),
447 PrettyDescriptor(caller_class->GetDescriptor()).c_str());
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700448 return NULL;
449 }
450
451 Object* new_obj = c->AllocObject();
452 if (new_obj == NULL) {
453 DCHECK(Thread::Current()->IsExceptionPending());
454 return NULL;
455 }
456
457 // invoke constructor; unlike reflection calls, we don't wrap exceptions
458 jclass jklass = AddLocalReference<jclass>(env, c);
459 jmethodID mid = EncodeMethod(init);
460 return env->NewObject(jklass, mid);
461}
462
Elliott Hughesd369bb72011-09-12 14:41:14 -0700463static JNINativeMethod gMethods[] = {
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700464 NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700465 NATIVE_METHOD(Class, desiredAssertionStatus, "()Z"),
466 NATIVE_METHOD(Class, getClassLoader, "(Ljava/lang/Class;)Ljava/lang/ClassLoader;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700467 NATIVE_METHOD(Class, getComponentType, "()Ljava/lang/Class;"),
Brian Carlstrom3a7b4f22011-09-17 15:01:57 -0700468 NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"),
Elliott Hughes80609252011-09-23 17:24:51 -0700469 NATIVE_METHOD(Class, getDeclaredConstructors, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;"),
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700470 NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;"),
Elliott Hughes80609252011-09-23 17:24:51 -0700471 NATIVE_METHOD(Class, getDeclaredFields, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;"),
472 NATIVE_METHOD(Class, getDeclaredMethods, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;"),
Jesse Wilson6bf19152011-09-29 13:12:33 -0400473 NATIVE_METHOD(Class, getDex, "()Lcom/android/dex/Dex;"),
Jesse Wilson163c4642011-10-12 10:42:15 -0400474 NATIVE_METHOD(Class, getNonInnerClassModifiers, "(Ljava/lang/Class;)I"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700475 NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700476 NATIVE_METHOD(Class, getSuperclass, "()Ljava/lang/Class;"),
Elliott Hughesdd8df692011-09-23 14:42:41 -0700477 NATIVE_METHOD(Class, isAssignableFrom, "(Ljava/lang/Class;)Z"),
478 NATIVE_METHOD(Class, isInstance, "(Ljava/lang/Object;)Z"),
Elliott Hughes6bdc3b22011-09-16 19:24:10 -0700479 NATIVE_METHOD(Class, isInterface, "()Z"),
480 NATIVE_METHOD(Class, isPrimitive, "()Z"),
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700481 NATIVE_METHOD(Class, newInstanceImpl, "()Ljava/lang/Object;"),
Elliott Hughesd369bb72011-09-12 14:41:14 -0700482};
483
484} // namespace
485
486void register_java_lang_Class(JNIEnv* env) {
487 jniRegisterNativeMethods(env, "java/lang/Class", gMethods, NELEM(gMethods));
488}
489
490} // namespace art