OSDN Git Service

Removing inaccurate and unmaintained docs.
[android-x86/dalvik.git] / vm / native / java_lang_Class.c
1 /*
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 /*
18  * java.lang.Class
19  */
20 #include "Dalvik.h"
21 #include "native/InternalNativePriv.h"
22
23
24 /*
25  * native public boolean desiredAssertionStatus()
26  *
27  * Determine the class-init-time assertion status of a class.  This is
28  * called from <clinit> in javac-generated classes that use the Java
29  * programming language "assert" keyword.
30  */
31 static void Dalvik_java_lang_Class_desiredAssertionStatus(const u4* args,
32     JValue* pResult)
33 {
34     ClassObject* thisPtr = (ClassObject*) args[0];
35     char* className = dvmDescriptorToName(thisPtr->descriptor);
36     int i;
37     bool enable = false;
38
39     /*
40      * Run through the list of arguments specified on the command line.  The
41      * last matching argument takes precedence.
42      */
43     for (i = 0; i < gDvm.assertionCtrlCount; i++) {
44         const AssertionControl* pCtrl = &gDvm.assertionCtrl[i];
45
46         if (pCtrl->isPackage) {
47             /*
48              * Given "dalvik/system/Debug" or "MyStuff", compute the
49              * length of the package portion of the class name string.
50              *
51              * Unlike most package operations, we allow matching on
52              * "sub-packages", so "dalvik..." will match "dalvik.Foo"
53              * and "dalvik.system.Foo".
54              *
55              * The pkgOrClass string looks like "dalvik/system/", i.e. it still
56              * has the terminating slash, so we can be sure we're comparing
57              * against full package component names.
58              */
59             const char* lastSlash;
60             int pkgLen;
61
62             lastSlash = strrchr(className, '/');
63             if (lastSlash == NULL) {
64                 pkgLen = 0;
65             } else {
66                 pkgLen = lastSlash - className +1;
67             }
68
69             if (pCtrl->pkgOrClassLen > pkgLen ||
70                 memcmp(pCtrl->pkgOrClass, className, pCtrl->pkgOrClassLen) != 0)
71             {
72                 LOGV("ASRT: pkg no match: '%s'(%d) vs '%s'\n",
73                     className, pkgLen, pCtrl->pkgOrClass);
74             } else {
75                 LOGV("ASRT: pkg match: '%s'(%d) vs '%s' --> %d\n",
76                     className, pkgLen, pCtrl->pkgOrClass, pCtrl->enable);
77                 enable = pCtrl->enable;
78             }
79         } else {
80             /*
81              * "pkgOrClass" holds a fully-qualified class name, converted from
82              * dot-form to slash-form.  An empty string means all classes.
83              */
84             if (pCtrl->pkgOrClass == NULL) {
85                 /* -esa/-dsa; see if class is a "system" class */
86                 if (strncmp(className, "java/", 5) != 0) {
87                     LOGV("ASRT: sys no match: '%s'\n", className);
88                 } else {
89                     LOGV("ASRT: sys match: '%s' --> %d\n",
90                         className, pCtrl->enable);
91                     enable = pCtrl->enable;
92                 }
93             } else if (*pCtrl->pkgOrClass == '\0') {
94                 LOGV("ASRT: class all: '%s' --> %d\n",
95                     className, pCtrl->enable);
96                 enable = pCtrl->enable;
97             } else {
98                 if (strcmp(pCtrl->pkgOrClass, className) != 0) {
99                     LOGV("ASRT: cls no match: '%s' vs '%s'\n",
100                         className, pCtrl->pkgOrClass);
101                 } else {
102                     LOGV("ASRT: cls match: '%s' vs '%s' --> %d\n",
103                         className, pCtrl->pkgOrClass, pCtrl->enable);
104                     enable = pCtrl->enable;
105                 }
106             }
107         }
108     }
109
110     free(className);
111     RETURN_INT(enable);
112 }
113
114 /*
115  * static public Class<?> classForName(String name, boolean initialize,
116  *     ClassLoader loader)
117  *
118  * Return the Class object associated with the class or interface with
119  * the specified name.
120  *
121  * "name" is in "binary name" format, e.g. "dalvik.system.Debug$1".
122  */
123 static void Dalvik_java_lang_Class_classForName(const u4* args, JValue* pResult)
124 {
125     StringObject* nameObj = (StringObject*) args[0];
126     bool initialize = (args[1] != 0);
127     Object* loader = (Object*) args[2];
128
129     RETURN_PTR(dvmFindClassByName(nameObj, loader, initialize));
130 }
131
132 /*
133  * static private ClassLoader getClassLoader(Class clazz)
134  *
135  * Return the class' defining class loader.
136  */
137 static void Dalvik_java_lang_Class_getClassLoader(const u4* args,
138     JValue* pResult)
139 {
140     ClassObject* clazz = (ClassObject*) args[0];
141
142     RETURN_PTR(clazz->classLoader);
143 }
144
145 /*
146  * public Class<?> getComponentType()
147  *
148  * If this is an array type, return the class of the elements; otherwise
149  * return NULL.
150  */
151 static void Dalvik_java_lang_Class_getComponentType(const u4* args,
152     JValue* pResult)
153 {
154     ClassObject* thisPtr = (ClassObject*) args[0];
155
156     if (!dvmIsArrayClass(thisPtr))
157         RETURN_PTR(NULL);
158
159     /*
160      * We can't just return thisPtr->elementClass, because that gives
161      * us the base type (e.g. X[][][] returns X).  If this is a multi-
162      * dimensional array, we have to do the lookup by name.
163      */
164     if (thisPtr->descriptor[1] == '[')
165         RETURN_PTR(dvmFindArrayClass(&thisPtr->descriptor[1],
166                    thisPtr->classLoader));
167     else
168         RETURN_PTR(thisPtr->elementClass);
169 }
170
171 /*
172  * private static Class<?>[] getDeclaredClasses(Class<?> clazz,
173  *     boolean publicOnly)
174  *
175  * Return an array with the classes that are declared by the specified class.
176  * If "publicOnly" is set, we strip out any classes that don't have "public"
177  * access.
178  */
179 static void Dalvik_java_lang_Class_getDeclaredClasses(const u4* args,
180     JValue* pResult)
181 {
182     ClassObject* clazz = (ClassObject*) args[0];
183     bool publicOnly = (args[1] != 0);
184     ArrayObject* classes;
185
186     classes = dvmGetDeclaredClasses(clazz);
187     if (classes == NULL) {
188         if (!dvmCheckException(dvmThreadSelf())) {
189             /* empty list, so create a zero-length array */
190             classes = dvmAllocArrayByClass(gDvm.classJavaLangClassArray,
191                         0, ALLOC_DEFAULT);
192         }
193     } else if (publicOnly) {
194         u4 count, newIdx, publicCount = 0;
195         ClassObject** pSource = (ClassObject**) classes->contents;
196         u4 length = classes->length;
197
198         /* count up public classes */
199         for (count = 0; count < length; count++) {
200             if (dvmIsPublicClass(pSource[count]))
201                 publicCount++;
202         }
203
204         /* create a new array to hold them */
205         ArrayObject* newClasses;
206         newClasses = dvmAllocArrayByClass(gDvm.classJavaLangClassArray,
207                         publicCount, ALLOC_DEFAULT);
208
209         /* copy them over */
210         for (count = newIdx = 0; count < length; count++) {
211             if (dvmIsPublicClass(pSource[count])) {
212                 dvmSetObjectArrayElement(newClasses, newIdx,
213                                          (Object *)pSource[count]);
214                 newIdx++;
215             }
216         }
217         assert(newIdx == publicCount);
218         dvmReleaseTrackedAlloc((Object*) classes, NULL);
219         classes = newClasses;
220     }
221
222     dvmReleaseTrackedAlloc((Object*) classes, NULL);
223     RETURN_PTR(classes);
224 }
225
226 /*
227  * static Constructor[] getDeclaredConstructors(Class clazz, boolean publicOnly)
228  *     throws SecurityException
229  */
230 static void Dalvik_java_lang_Class_getDeclaredConstructors(const u4* args,
231     JValue* pResult)
232 {
233     ClassObject* clazz = (ClassObject*) args[0];
234     bool publicOnly = (args[1] != 0);
235     ArrayObject* constructors;
236
237     constructors = dvmGetDeclaredConstructors(clazz, publicOnly);
238     dvmReleaseTrackedAlloc((Object*) constructors, NULL);
239
240     RETURN_PTR(constructors);
241 }
242
243 /*
244  * static Field[] getDeclaredFields(Class klass, boolean publicOnly)
245  *     throws SecurityException
246  */
247 static void Dalvik_java_lang_Class_getDeclaredFields(const u4* args,
248     JValue* pResult)
249 {
250     ClassObject* clazz = (ClassObject*) args[0];
251     bool publicOnly = (args[1] != 0);
252     ArrayObject* fields;
253
254     fields = dvmGetDeclaredFields(clazz, publicOnly);
255     dvmReleaseTrackedAlloc((Object*) fields, NULL);
256
257     RETURN_PTR(fields);
258 }
259
260 /*
261  * static Method[] getDeclaredMethods(Class clazz, boolean publicOnly)
262  *     throws SecurityException
263  */
264 static void Dalvik_java_lang_Class_getDeclaredMethods(const u4* args,
265     JValue* pResult)
266 {
267     ClassObject* clazz = (ClassObject*) args[0];
268     bool publicOnly = (args[1] != 0);
269     ArrayObject* methods;
270
271     methods = dvmGetDeclaredMethods(clazz, publicOnly);
272     dvmReleaseTrackedAlloc((Object*) methods, NULL);
273
274     RETURN_PTR(methods);
275 }
276
277 /*
278  * Class[] getInterfaces()
279  */
280 static void Dalvik_java_lang_Class_getInterfaces(const u4* args,
281     JValue* pResult)
282 {
283     ClassObject* clazz = (ClassObject*) args[0];
284     ArrayObject* interfaces;
285
286     interfaces = dvmGetInterfaces(clazz);
287     dvmReleaseTrackedAlloc((Object*) interfaces, NULL);
288
289     RETURN_PTR(interfaces);
290 }
291
292 /*
293  * private static int getModifiers(Class klass, boolean
294  *     ignoreInnerClassesAttrib)
295  *
296  * Return the class' modifier flags.  If "ignoreInnerClassesAttrib" is false,
297  * and this is an inner class, we return the access flags from the inner class
298  * attribute.
299  */
300 static void Dalvik_java_lang_Class_getModifiers(const u4* args, JValue* pResult)
301 {
302     ClassObject* clazz = (ClassObject*) args[0];
303     bool ignoreInner = args[1];
304     u4 accessFlags;
305
306     accessFlags = clazz->accessFlags & JAVA_FLAGS_MASK;
307
308     if (!ignoreInner) {
309         /* see if we have an InnerClass annotation with flags in it */
310         StringObject* className = NULL;
311         int innerFlags;
312
313         if (dvmGetInnerClass(clazz, &className, &innerFlags))
314             accessFlags = innerFlags & JAVA_FLAGS_MASK;
315
316         dvmReleaseTrackedAlloc((Object*) className, NULL);
317     }
318
319     RETURN_INT(accessFlags);
320 }
321
322 /*
323  * private native String getNameNative()
324  *
325  * Return the class' name. The exact format is bizarre, but it's the specified
326  * behavior: keywords for primitive types, regular "[I" form for primitive
327  * arrays (so "int" but "[I"), and arrays of reference types written
328  * between "L" and ";" but with dots rather than slashes (so "java.lang.String"
329  * but "[Ljava.lang.String;"). Madness.
330  */
331 static void Dalvik_java_lang_Class_getNameNative(const u4* args, JValue* pResult)
332 {
333     ClassObject* clazz = (ClassObject*) args[0];
334     const char* descriptor = clazz->descriptor;
335     StringObject* nameObj;
336
337     if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
338         /*
339          * The descriptor indicates that this is the class for
340          * a primitive type; special-case the return value.
341          */
342         const char* name;
343         switch (descriptor[0]) {
344             case 'Z': name = "boolean"; break;
345             case 'B': name = "byte";    break;
346             case 'C': name = "char";    break;
347             case 'S': name = "short";   break;
348             case 'I': name = "int";     break;
349             case 'J': name = "long";    break;
350             case 'F': name = "float";   break;
351             case 'D': name = "double";  break;
352             case 'V': name = "void";    break;
353             default: {
354                 LOGE("Unknown primitive type '%c'\n", descriptor[0]);
355                 assert(false);
356                 RETURN_PTR(NULL);
357             }
358         }
359
360         nameObj = dvmCreateStringFromCstr(name);
361     } else {
362         /*
363          * Convert the UTF-8 name to a java.lang.String. The
364          * name must use '.' to separate package components.
365          *
366          * TODO: this could be more efficient. Consider a custom
367          * conversion function here that walks the string once and
368          * avoids the allocation for the common case (name less than,
369          * say, 128 bytes).
370          */
371         char* dotName = dvmDescriptorToDot(clazz->descriptor);
372         nameObj = dvmCreateStringFromCstr(dotName);
373         free(dotName);
374     }
375
376     dvmReleaseTrackedAlloc((Object*) nameObj, NULL);
377     RETURN_PTR(nameObj);
378 }
379
380 /*
381  * Return the superclass for instances of this class.
382  *
383  * If the class represents a java/lang/Object, an interface, a primitive
384  * type, or void (which *is* a primitive type??), return NULL.
385  *
386  * For an array, return the java/lang/Object ClassObject.
387  */
388 static void Dalvik_java_lang_Class_getSuperclass(const u4* args,
389     JValue* pResult)
390 {
391     ClassObject* clazz = (ClassObject*) args[0];
392
393     if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz))
394         RETURN_PTR(NULL);
395     else
396         RETURN_PTR(clazz->super);
397 }
398
399 /*
400  * public boolean isAssignableFrom(Class<?> cls)
401  *
402  * Determine if this class is either the same as, or is a superclass or
403  * superinterface of, the class specified in the "cls" parameter.
404  */
405 static void Dalvik_java_lang_Class_isAssignableFrom(const u4* args,
406     JValue* pResult)
407 {
408     ClassObject* thisPtr = (ClassObject*) args[0];
409     ClassObject* testClass = (ClassObject*) args[1];
410
411     if (testClass == NULL) {
412         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
413         RETURN_INT(false);
414     }
415     RETURN_INT(dvmInstanceof(testClass, thisPtr));
416 }
417
418 /*
419  * public boolean isInstance(Object o)
420  *
421  * Dynamic equivalent of Java programming language "instanceof".
422  */
423 static void Dalvik_java_lang_Class_isInstance(const u4* args,
424     JValue* pResult)
425 {
426     ClassObject* thisPtr = (ClassObject*) args[0];
427     Object* testObj = (Object*) args[1];
428
429     if (testObj == NULL)
430         RETURN_INT(false);
431     RETURN_INT(dvmInstanceof(testObj->clazz, thisPtr));
432 }
433
434 /*
435  * public boolean isInterface()
436  */
437 static void Dalvik_java_lang_Class_isInterface(const u4* args,
438     JValue* pResult)
439 {
440     ClassObject* thisPtr = (ClassObject*) args[0];
441
442     RETURN_INT(dvmIsInterfaceClass(thisPtr));
443 }
444
445 /*
446  * public boolean isPrimitive()
447  */
448 static void Dalvik_java_lang_Class_isPrimitive(const u4* args,
449     JValue* pResult)
450 {
451     ClassObject* thisPtr = (ClassObject*) args[0];
452
453     RETURN_INT(dvmIsPrimitiveClass(thisPtr));
454 }
455
456 /*
457  * public T newInstance() throws InstantiationException, IllegalAccessException
458  *
459  * Create a new instance of this class.
460  */
461 static void Dalvik_java_lang_Class_newInstance(const u4* args, JValue* pResult)
462 {
463     Thread* self = dvmThreadSelf();
464     ClassObject* clazz = (ClassObject*) args[0];
465     Method* init;
466     Object* newObj;
467
468     /* can't instantiate these */
469     if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz)
470         || dvmIsArrayClass(clazz) || dvmIsAbstractClass(clazz))
471     {
472         LOGD("newInstance failed: p%d i%d [%d a%d\n",
473             dvmIsPrimitiveClass(clazz), dvmIsInterfaceClass(clazz),
474             dvmIsArrayClass(clazz), dvmIsAbstractClass(clazz));
475         dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationException;",
476             clazz->descriptor);
477         RETURN_VOID();
478     }
479
480     /* initialize the class if it hasn't been already */
481     if (!dvmIsClassInitialized(clazz)) {
482         if (!dvmInitClass(clazz)) {
483             LOGW("Class init failed in newInstance call (%s)\n",
484                 clazz->descriptor);
485             assert(dvmCheckException(self));
486             RETURN_VOID();
487         }
488     }
489
490     /* find the "nullary" constructor */
491     init = dvmFindDirectMethodByDescriptor(clazz, "<init>", "()V");
492     if (init == NULL) {
493         /* common cause: secret "this" arg on non-static inner class ctor */
494         LOGD("newInstance failed: no <init>()\n");
495         dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationException;",
496             clazz->descriptor);
497         RETURN_VOID();
498     }
499
500     /*
501      * Verify access from the call site.
502      *
503      * First, make sure the method invoking Class.newInstance() has permission
504      * to access the class.
505      *
506      * Second, make sure it has permission to invoke the constructor.  The
507      * constructor must be public or, if the caller is in the same package,
508      * have package scope.
509      */
510     ClassObject* callerClass = dvmGetCaller2Class(self->curFrame);
511
512     if (!dvmCheckClassAccess(callerClass, clazz)) {
513         LOGD("newInstance failed: %s not accessible to %s\n",
514             clazz->descriptor, callerClass->descriptor);
515         dvmThrowException("Ljava/lang/IllegalAccessException;",
516             "access to class not allowed");
517         RETURN_VOID();
518     }
519     if (!dvmCheckMethodAccess(callerClass, init)) {
520         LOGD("newInstance failed: %s.<init>() not accessible to %s\n",
521             clazz->descriptor, callerClass->descriptor);
522         dvmThrowException("Ljava/lang/IllegalAccessException;",
523             "access to constructor not allowed");
524         RETURN_VOID();
525     }
526
527     newObj = dvmAllocObject(clazz, ALLOC_DEFAULT);
528     JValue unused;
529
530     /* invoke constructor; unlike reflection calls, we don't wrap exceptions */
531     dvmCallMethod(self, init, newObj, &unused);
532     dvmReleaseTrackedAlloc(newObj, NULL);
533
534     RETURN_PTR(newObj);
535 }
536
537 /*
538  * private Object[] getSignatureAnnotation()
539  *
540  * Returns the signature annotation array.
541  */
542 static void Dalvik_java_lang_Class_getSignatureAnnotation(const u4* args,
543     JValue* pResult)
544 {
545     ClassObject* clazz = (ClassObject*) args[0];
546     ArrayObject* arr = dvmGetClassSignatureAnnotation(clazz);
547
548     dvmReleaseTrackedAlloc((Object*) arr, NULL);
549     RETURN_PTR(arr);
550 }
551
552 /*
553  * public Class getDeclaringClass()
554  *
555  * Get the class that encloses this class (if any).
556  */
557 static void Dalvik_java_lang_Class_getDeclaringClass(const u4* args,
558     JValue* pResult)
559 {
560     ClassObject* clazz = (ClassObject*) args[0];
561
562     ClassObject* enclosing = dvmGetDeclaringClass(clazz);
563     dvmReleaseTrackedAlloc((Object*) enclosing, NULL);
564     RETURN_PTR(enclosing);
565 }
566
567 /*
568  * public Class getEnclosingClass()
569  *
570  * Get the class that encloses this class (if any).
571  */
572 static void Dalvik_java_lang_Class_getEnclosingClass(const u4* args,
573     JValue* pResult)
574 {
575     ClassObject* clazz = (ClassObject*) args[0];
576
577     ClassObject* enclosing = dvmGetEnclosingClass(clazz);
578     dvmReleaseTrackedAlloc((Object*) enclosing, NULL);
579     RETURN_PTR(enclosing);
580 }
581
582 /*
583  * public Constructor getEnclosingConstructor()
584  *
585  * Get the constructor that encloses this class (if any).
586  */
587 static void Dalvik_java_lang_Class_getEnclosingConstructor(const u4* args,
588     JValue* pResult)
589 {
590     ClassObject* clazz = (ClassObject*) args[0];
591
592     Object* enclosing = dvmGetEnclosingMethod(clazz);
593     if (enclosing != NULL) {
594         dvmReleaseTrackedAlloc(enclosing, NULL);
595         if (enclosing->clazz == gDvm.classJavaLangReflectConstructor) {
596             RETURN_PTR(enclosing);
597         }
598         assert(enclosing->clazz == gDvm.classJavaLangReflectMethod);
599     }
600     RETURN_PTR(NULL);
601 }
602
603 /*
604  * public Method getEnclosingMethod()
605  *
606  * Get the method that encloses this class (if any).
607  */
608 static void Dalvik_java_lang_Class_getEnclosingMethod(const u4* args,
609     JValue* pResult)
610 {
611     ClassObject* clazz = (ClassObject*) args[0];
612
613     Object* enclosing = dvmGetEnclosingMethod(clazz);
614     if (enclosing != NULL) {
615         dvmReleaseTrackedAlloc(enclosing, NULL);
616         if (enclosing->clazz == gDvm.classJavaLangReflectMethod) {
617             RETURN_PTR(enclosing);
618         }
619         assert(enclosing->clazz == gDvm.classJavaLangReflectConstructor);
620     }
621     RETURN_PTR(NULL);
622 }
623
624 #if 0
625 static void Dalvik_java_lang_Class_getGenericInterfaces(const u4* args,
626     JValue* pResult)
627 {
628     dvmThrowException("Ljava/lang/UnsupportedOperationException;",
629         "native method not implemented");
630
631     RETURN_PTR(NULL);
632 }
633
634 static void Dalvik_java_lang_Class_getGenericSuperclass(const u4* args,
635     JValue* pResult)
636 {
637     dvmThrowException("Ljava/lang/UnsupportedOperationException;",
638         "native method not implemented");
639
640     RETURN_PTR(NULL);
641 }
642
643 static void Dalvik_java_lang_Class_getTypeParameters(const u4* args,
644     JValue* pResult)
645 {
646     dvmThrowException("Ljava/lang/UnsupportedOperationException;",
647         "native method not implemented");
648
649     RETURN_PTR(NULL);
650 }
651 #endif
652
653 /*
654  * public boolean isAnonymousClass()
655  *
656  * Returns true if this is an "anonymous" class.
657  */
658 static void Dalvik_java_lang_Class_isAnonymousClass(const u4* args,
659     JValue* pResult)
660 {
661     ClassObject* clazz = (ClassObject*) args[0];
662     StringObject* className = NULL;
663     int accessFlags;
664
665     /*
666      * If this has an InnerClass annotation, pull it out.  Lack of the
667      * annotation, or an annotation with a NULL class name, indicates
668      * that this is an anonymous inner class.
669      */
670     if (!dvmGetInnerClass(clazz, &className, &accessFlags))
671         RETURN_BOOLEAN(false);
672
673     dvmReleaseTrackedAlloc((Object*) className, NULL);
674     RETURN_BOOLEAN(className == NULL);
675 }
676
677 /*
678  * private Annotation[] getDeclaredAnnotations()
679  *
680  * Return the annotations declared on this class.
681  */
682 static void Dalvik_java_lang_Class_getDeclaredAnnotations(const u4* args,
683     JValue* pResult)
684 {
685     ClassObject* clazz = (ClassObject*) args[0];
686
687     ArrayObject* annos = dvmGetClassAnnotations(clazz);
688     dvmReleaseTrackedAlloc((Object*) annos, NULL);
689     RETURN_PTR(annos);
690 }
691
692 /*
693  * public String getInnerClassName()
694  *
695  * Returns the simple name of a member class or local class, or null otherwise.
696  */
697 static void Dalvik_java_lang_Class_getInnerClassName(const u4* args,
698     JValue* pResult)
699 {
700     ClassObject* clazz = (ClassObject*) args[0];
701     StringObject* nameObj;
702     int flags;
703
704     if (dvmGetInnerClass(clazz, &nameObj, &flags)) {
705         dvmReleaseTrackedAlloc((Object*) nameObj, NULL);
706         RETURN_PTR(nameObj);
707     } else {
708         RETURN_PTR(NULL);
709     }
710 }
711
712 /*
713  * static native void setAccessibleNoCheck(AccessibleObject ao, boolean flag);
714  */
715 static void Dalvik_java_lang_Class_setAccessibleNoCheck(const u4* args,
716     JValue* pResult)
717 {
718     Object* target = (Object*) args[0];
719     u4 flag = (u4) args[1];
720
721     dvmSetFieldBoolean(target, gDvm.offJavaLangReflectAccessibleObject_flag,
722             flag);
723 }
724
725 const DalvikNativeMethod dvm_java_lang_Class[] = {
726     { "desiredAssertionStatus", "()Z",
727         Dalvik_java_lang_Class_desiredAssertionStatus },
728     { "classForName",           "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;",
729         Dalvik_java_lang_Class_classForName },
730     { "getClassLoader",         "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",
731         Dalvik_java_lang_Class_getClassLoader },
732     { "getComponentType",       "()Ljava/lang/Class;",
733         Dalvik_java_lang_Class_getComponentType },
734     { "getSignatureAnnotation",  "()[Ljava/lang/Object;",
735         Dalvik_java_lang_Class_getSignatureAnnotation },
736     { "getDeclaredClasses",     "(Ljava/lang/Class;Z)[Ljava/lang/Class;",
737         Dalvik_java_lang_Class_getDeclaredClasses },
738     { "getDeclaredConstructors", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;",
739         Dalvik_java_lang_Class_getDeclaredConstructors },
740     { "getDeclaredFields",      "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;",
741         Dalvik_java_lang_Class_getDeclaredFields },
742     { "getDeclaredMethods",     "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",
743         Dalvik_java_lang_Class_getDeclaredMethods },
744     { "getInterfaces",          "()[Ljava/lang/Class;",
745         Dalvik_java_lang_Class_getInterfaces },
746     { "getModifiers",           "(Ljava/lang/Class;Z)I",
747         Dalvik_java_lang_Class_getModifiers },
748     { "getNameNative",                "()Ljava/lang/String;",
749         Dalvik_java_lang_Class_getNameNative },
750     { "getSuperclass",          "()Ljava/lang/Class;",
751         Dalvik_java_lang_Class_getSuperclass },
752     { "isAssignableFrom",       "(Ljava/lang/Class;)Z",
753         Dalvik_java_lang_Class_isAssignableFrom },
754     { "isInstance",             "(Ljava/lang/Object;)Z",
755         Dalvik_java_lang_Class_isInstance },
756     { "isInterface",            "()Z",
757         Dalvik_java_lang_Class_isInterface },
758     { "isPrimitive",            "()Z",
759         Dalvik_java_lang_Class_isPrimitive },
760     { "newInstanceImpl",        "()Ljava/lang/Object;",
761         Dalvik_java_lang_Class_newInstance },
762     { "getDeclaringClass",      "()Ljava/lang/Class;",
763         Dalvik_java_lang_Class_getDeclaringClass },
764     { "getEnclosingClass",      "()Ljava/lang/Class;",
765         Dalvik_java_lang_Class_getEnclosingClass },
766     { "getEnclosingConstructor", "()Ljava/lang/reflect/Constructor;",
767         Dalvik_java_lang_Class_getEnclosingConstructor },
768     { "getEnclosingMethod",     "()Ljava/lang/reflect/Method;",
769         Dalvik_java_lang_Class_getEnclosingMethod },
770 #if 0
771     { "getGenericInterfaces",   "()[Ljava/lang/reflect/Type;",
772         Dalvik_java_lang_Class_getGenericInterfaces },
773     { "getGenericSuperclass",   "()Ljava/lang/reflect/Type;",
774         Dalvik_java_lang_Class_getGenericSuperclass },
775     { "getTypeParameters",      "()Ljava/lang/reflect/TypeVariable;",
776         Dalvik_java_lang_Class_getTypeParameters },
777 #endif
778     { "isAnonymousClass",       "()Z",
779         Dalvik_java_lang_Class_isAnonymousClass },
780     { "getDeclaredAnnotations", "()[Ljava/lang/annotation/Annotation;",
781         Dalvik_java_lang_Class_getDeclaredAnnotations },
782     { "getInnerClassName",       "()Ljava/lang/String;",
783         Dalvik_java_lang_Class_getInnerClassName },
784     { "setAccessibleNoCheck",   "(Ljava/lang/reflect/AccessibleObject;Z)V",
785         Dalvik_java_lang_Class_setAccessibleNoCheck },
786     { NULL, NULL, NULL },
787 };