OSDN Git Service

1cd31dfe90f2e2cc85546dd1c206a7177c0ea649
[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  * static native Member getDeclaredConstructorOrMethod(
279  *     Class clazz, String name, Class[] args);
280  */
281 static void Dalvik_java_lang_Class_getDeclaredConstructorOrMethod(
282     const u4* args, JValue* pResult)
283 {
284     ClassObject* clazz = (ClassObject*) args[0];
285     StringObject* nameObj = (StringObject*) args[1];
286     ArrayObject* methodArgs = (ArrayObject*) args[2];
287
288     Object* methodObj;
289
290     methodObj = dvmGetDeclaredConstructorOrMethod(clazz, nameObj, methodArgs);
291     dvmReleaseTrackedAlloc(methodObj, NULL);
292
293     RETURN_PTR(methodObj);
294 }
295
296 /*
297  * Class[] getInterfaces()
298  */
299 static void Dalvik_java_lang_Class_getInterfaces(const u4* args,
300     JValue* pResult)
301 {
302     ClassObject* clazz = (ClassObject*) args[0];
303     ArrayObject* interfaces;
304
305     interfaces = dvmGetInterfaces(clazz);
306     dvmReleaseTrackedAlloc((Object*) interfaces, NULL);
307
308     RETURN_PTR(interfaces);
309 }
310
311 /*
312  * private static int getModifiers(Class klass, boolean
313  *     ignoreInnerClassesAttrib)
314  *
315  * Return the class' modifier flags.  If "ignoreInnerClassesAttrib" is false,
316  * and this is an inner class, we return the access flags from the inner class
317  * attribute.
318  */
319 static void Dalvik_java_lang_Class_getModifiers(const u4* args, JValue* pResult)
320 {
321     ClassObject* clazz = (ClassObject*) args[0];
322     bool ignoreInner = args[1];
323     u4 accessFlags;
324
325     accessFlags = clazz->accessFlags & JAVA_FLAGS_MASK;
326
327     if (!ignoreInner) {
328         /* see if we have an InnerClass annotation with flags in it */
329         StringObject* className = NULL;
330         int innerFlags;
331
332         if (dvmGetInnerClass(clazz, &className, &innerFlags))
333             accessFlags = innerFlags & JAVA_FLAGS_MASK;
334
335         dvmReleaseTrackedAlloc((Object*) className, NULL);
336     }
337
338     RETURN_INT(accessFlags);
339 }
340
341 /*
342  * private native String getNameNative()
343  *
344  * Return the class' name. The exact format is bizarre, but it's the specified
345  * behavior: keywords for primitive types, regular "[I" form for primitive
346  * arrays (so "int" but "[I"), and arrays of reference types written
347  * between "L" and ";" but with dots rather than slashes (so "java.lang.String"
348  * but "[Ljava.lang.String;"). Madness.
349  */
350 static void Dalvik_java_lang_Class_getNameNative(const u4* args, JValue* pResult)
351 {
352     ClassObject* clazz = (ClassObject*) args[0];
353     const char* descriptor = clazz->descriptor;
354     StringObject* nameObj;
355
356     if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
357         /*
358          * The descriptor indicates that this is the class for
359          * a primitive type; special-case the return value.
360          */
361         const char* name;
362         switch (descriptor[0]) {
363             case 'Z': name = "boolean"; break;
364             case 'B': name = "byte";    break;
365             case 'C': name = "char";    break;
366             case 'S': name = "short";   break;
367             case 'I': name = "int";     break;
368             case 'J': name = "long";    break;
369             case 'F': name = "float";   break;
370             case 'D': name = "double";  break;
371             case 'V': name = "void";    break;
372             default: {
373                 LOGE("Unknown primitive type '%c'\n", descriptor[0]);
374                 assert(false);
375                 RETURN_PTR(NULL);
376             }
377         }
378
379         nameObj = dvmCreateStringFromCstr(name);
380     } else {
381         /*
382          * Convert the UTF-8 name to a java.lang.String. The
383          * name must use '.' to separate package components.
384          *
385          * TODO: this could be more efficient. Consider a custom
386          * conversion function here that walks the string once and
387          * avoids the allocation for the common case (name less than,
388          * say, 128 bytes).
389          */
390         char* dotName = dvmDescriptorToDot(clazz->descriptor);
391         nameObj = dvmCreateStringFromCstr(dotName);
392         free(dotName);
393     }
394
395     dvmReleaseTrackedAlloc((Object*) nameObj, NULL);
396     RETURN_PTR(nameObj);
397 }
398
399 /*
400  * Return the superclass for instances of this class.
401  *
402  * If the class represents a java/lang/Object, an interface, a primitive
403  * type, or void (which *is* a primitive type??), return NULL.
404  *
405  * For an array, return the java/lang/Object ClassObject.
406  */
407 static void Dalvik_java_lang_Class_getSuperclass(const u4* args,
408     JValue* pResult)
409 {
410     ClassObject* clazz = (ClassObject*) args[0];
411
412     if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz))
413         RETURN_PTR(NULL);
414     else
415         RETURN_PTR(clazz->super);
416 }
417
418 /*
419  * public boolean isAssignableFrom(Class<?> cls)
420  *
421  * Determine if this class is either the same as, or is a superclass or
422  * superinterface of, the class specified in the "cls" parameter.
423  */
424 static void Dalvik_java_lang_Class_isAssignableFrom(const u4* args,
425     JValue* pResult)
426 {
427     ClassObject* thisPtr = (ClassObject*) args[0];
428     ClassObject* testClass = (ClassObject*) args[1];
429
430     if (testClass == NULL) {
431         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
432         RETURN_INT(false);
433     }
434     RETURN_INT(dvmInstanceof(testClass, thisPtr));
435 }
436
437 /*
438  * public boolean isInstance(Object o)
439  *
440  * Dynamic equivalent of Java programming language "instanceof".
441  */
442 static void Dalvik_java_lang_Class_isInstance(const u4* args,
443     JValue* pResult)
444 {
445     ClassObject* thisPtr = (ClassObject*) args[0];
446     Object* testObj = (Object*) args[1];
447
448     if (testObj == NULL)
449         RETURN_INT(false);
450     RETURN_INT(dvmInstanceof(testObj->clazz, thisPtr));
451 }
452
453 /*
454  * public boolean isInterface()
455  */
456 static void Dalvik_java_lang_Class_isInterface(const u4* args,
457     JValue* pResult)
458 {
459     ClassObject* thisPtr = (ClassObject*) args[0];
460
461     RETURN_INT(dvmIsInterfaceClass(thisPtr));
462 }
463
464 /*
465  * public boolean isPrimitive()
466  */
467 static void Dalvik_java_lang_Class_isPrimitive(const u4* args,
468     JValue* pResult)
469 {
470     ClassObject* thisPtr = (ClassObject*) args[0];
471
472     RETURN_INT(dvmIsPrimitiveClass(thisPtr));
473 }
474
475 /*
476  * public T newInstance() throws InstantiationException, IllegalAccessException
477  *
478  * Create a new instance of this class.
479  */
480 static void Dalvik_java_lang_Class_newInstance(const u4* args, JValue* pResult)
481 {
482     Thread* self = dvmThreadSelf();
483     ClassObject* clazz = (ClassObject*) args[0];
484     Method* init;
485     Object* newObj;
486
487     /* can't instantiate these */
488     if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz)
489         || dvmIsArrayClass(clazz) || dvmIsAbstractClass(clazz))
490     {
491         LOGD("newInstance failed: p%d i%d [%d a%d\n",
492             dvmIsPrimitiveClass(clazz), dvmIsInterfaceClass(clazz),
493             dvmIsArrayClass(clazz), dvmIsAbstractClass(clazz));
494         dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationException;",
495             clazz->descriptor);
496         RETURN_VOID();
497     }
498
499     /* initialize the class if it hasn't been already */
500     if (!dvmIsClassInitialized(clazz)) {
501         if (!dvmInitClass(clazz)) {
502             LOGW("Class init failed in newInstance call (%s)\n",
503                 clazz->descriptor);
504             assert(dvmCheckException(self));
505             RETURN_VOID();
506         }
507     }
508
509     /* find the "nullary" constructor */
510     init = dvmFindDirectMethodByDescriptor(clazz, "<init>", "()V");
511     if (init == NULL) {
512         /* common cause: secret "this" arg on non-static inner class ctor */
513         LOGD("newInstance failed: no <init>()\n");
514         dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationException;",
515             clazz->descriptor);
516         RETURN_VOID();
517     }
518
519     /*
520      * Verify access from the call site.
521      *
522      * First, make sure the method invoking Class.newInstance() has permission
523      * to access the class.
524      *
525      * Second, make sure it has permission to invoke the constructor.  The
526      * constructor must be public or, if the caller is in the same package,
527      * have package scope.
528      */
529     ClassObject* callerClass = dvmGetCaller2Class(self->curFrame);
530
531     if (!dvmCheckClassAccess(callerClass, clazz)) {
532         LOGD("newInstance failed: %s not accessible to %s\n",
533             clazz->descriptor, callerClass->descriptor);
534         dvmThrowException("Ljava/lang/IllegalAccessException;",
535             "access to class not allowed");
536         RETURN_VOID();
537     }
538     if (!dvmCheckMethodAccess(callerClass, init)) {
539         LOGD("newInstance failed: %s.<init>() not accessible to %s\n",
540             clazz->descriptor, callerClass->descriptor);
541         dvmThrowException("Ljava/lang/IllegalAccessException;",
542             "access to constructor not allowed");
543         RETURN_VOID();
544     }
545
546     newObj = dvmAllocObject(clazz, ALLOC_DEFAULT);
547     JValue unused;
548
549     /* invoke constructor; unlike reflection calls, we don't wrap exceptions */
550     dvmCallMethod(self, init, newObj, &unused);
551     dvmReleaseTrackedAlloc(newObj, NULL);
552
553     RETURN_PTR(newObj);
554 }
555
556 /*
557  * private Object[] getSignatureAnnotation()
558  *
559  * Returns the signature annotation array.
560  */
561 static void Dalvik_java_lang_Class_getSignatureAnnotation(const u4* args,
562     JValue* pResult)
563 {
564     ClassObject* clazz = (ClassObject*) args[0];
565     ArrayObject* arr = dvmGetClassSignatureAnnotation(clazz);
566
567     dvmReleaseTrackedAlloc((Object*) arr, NULL);
568     RETURN_PTR(arr);
569 }
570
571 /*
572  * public Class getDeclaringClass()
573  *
574  * Get the class that encloses this class (if any).
575  */
576 static void Dalvik_java_lang_Class_getDeclaringClass(const u4* args,
577     JValue* pResult)
578 {
579     ClassObject* clazz = (ClassObject*) args[0];
580
581     ClassObject* enclosing = dvmGetDeclaringClass(clazz);
582     dvmReleaseTrackedAlloc((Object*) enclosing, NULL);
583     RETURN_PTR(enclosing);
584 }
585
586 /*
587  * public Class getEnclosingClass()
588  *
589  * Get the class that encloses this class (if any).
590  */
591 static void Dalvik_java_lang_Class_getEnclosingClass(const u4* args,
592     JValue* pResult)
593 {
594     ClassObject* clazz = (ClassObject*) args[0];
595
596     ClassObject* enclosing = dvmGetEnclosingClass(clazz);
597     dvmReleaseTrackedAlloc((Object*) enclosing, NULL);
598     RETURN_PTR(enclosing);
599 }
600
601 /*
602  * public Constructor getEnclosingConstructor()
603  *
604  * Get the constructor that encloses this class (if any).
605  */
606 static void Dalvik_java_lang_Class_getEnclosingConstructor(const u4* args,
607     JValue* pResult)
608 {
609     ClassObject* clazz = (ClassObject*) args[0];
610
611     Object* enclosing = dvmGetEnclosingMethod(clazz);
612     if (enclosing != NULL) {
613         dvmReleaseTrackedAlloc(enclosing, NULL);
614         if (enclosing->clazz == gDvm.classJavaLangReflectConstructor) {
615             RETURN_PTR(enclosing);
616         }
617         assert(enclosing->clazz == gDvm.classJavaLangReflectMethod);
618     }
619     RETURN_PTR(NULL);
620 }
621
622 /*
623  * public Method getEnclosingMethod()
624  *
625  * Get the method that encloses this class (if any).
626  */
627 static void Dalvik_java_lang_Class_getEnclosingMethod(const u4* args,
628     JValue* pResult)
629 {
630     ClassObject* clazz = (ClassObject*) args[0];
631
632     Object* enclosing = dvmGetEnclosingMethod(clazz);
633     if (enclosing != NULL) {
634         dvmReleaseTrackedAlloc(enclosing, NULL);
635         if (enclosing->clazz == gDvm.classJavaLangReflectMethod) {
636             RETURN_PTR(enclosing);
637         }
638         assert(enclosing->clazz == gDvm.classJavaLangReflectConstructor);
639     }
640     RETURN_PTR(NULL);
641 }
642
643 #if 0
644 static void Dalvik_java_lang_Class_getGenericInterfaces(const u4* args,
645     JValue* pResult)
646 {
647     dvmThrowException("Ljava/lang/UnsupportedOperationException;",
648         "native method not implemented");
649
650     RETURN_PTR(NULL);
651 }
652
653 static void Dalvik_java_lang_Class_getGenericSuperclass(const u4* args,
654     JValue* pResult)
655 {
656     dvmThrowException("Ljava/lang/UnsupportedOperationException;",
657         "native method not implemented");
658
659     RETURN_PTR(NULL);
660 }
661
662 static void Dalvik_java_lang_Class_getTypeParameters(const u4* args,
663     JValue* pResult)
664 {
665     dvmThrowException("Ljava/lang/UnsupportedOperationException;",
666         "native method not implemented");
667
668     RETURN_PTR(NULL);
669 }
670 #endif
671
672 /*
673  * public boolean isAnonymousClass()
674  *
675  * Returns true if this is an "anonymous" class.
676  */
677 static void Dalvik_java_lang_Class_isAnonymousClass(const u4* args,
678     JValue* pResult)
679 {
680     ClassObject* clazz = (ClassObject*) args[0];
681     StringObject* className = NULL;
682     int accessFlags;
683
684     /*
685      * If this has an InnerClass annotation, pull it out.  Lack of the
686      * annotation, or an annotation with a NULL class name, indicates
687      * that this is an anonymous inner class.
688      */
689     if (!dvmGetInnerClass(clazz, &className, &accessFlags))
690         RETURN_BOOLEAN(false);
691
692     dvmReleaseTrackedAlloc((Object*) className, NULL);
693     RETURN_BOOLEAN(className == NULL);
694 }
695
696 /*
697  * private Annotation[] getDeclaredAnnotations()
698  *
699  * Return the annotations declared on this class.
700  */
701 static void Dalvik_java_lang_Class_getDeclaredAnnotations(const u4* args,
702     JValue* pResult)
703 {
704     ClassObject* clazz = (ClassObject*) args[0];
705
706     ArrayObject* annos = dvmGetClassAnnotations(clazz);
707     dvmReleaseTrackedAlloc((Object*) annos, NULL);
708     RETURN_PTR(annos);
709 }
710
711 /*
712  * public String getInnerClassName()
713  *
714  * Returns the simple name of a member class or local class, or null otherwise.
715  */
716 static void Dalvik_java_lang_Class_getInnerClassName(const u4* args,
717     JValue* pResult)
718 {
719     ClassObject* clazz = (ClassObject*) args[0];
720     StringObject* nameObj;
721     int flags;
722
723     if (dvmGetInnerClass(clazz, &nameObj, &flags)) {
724         dvmReleaseTrackedAlloc((Object*) nameObj, NULL);
725         RETURN_PTR(nameObj);
726     } else {
727         RETURN_PTR(NULL);
728     }
729 }
730
731 /*
732  * static native void setAccessibleNoCheck(AccessibleObject ao, boolean flag);
733  */
734 static void Dalvik_java_lang_Class_setAccessibleNoCheck(const u4* args,
735     JValue* pResult)
736 {
737     Object* target = (Object*) args[0];
738     u4 flag = (u4) args[1];
739
740     dvmSetFieldBoolean(target, gDvm.offJavaLangReflectAccessibleObject_flag,
741             flag);
742 }
743
744 const DalvikNativeMethod dvm_java_lang_Class[] = {
745     { "desiredAssertionStatus", "()Z",
746         Dalvik_java_lang_Class_desiredAssertionStatus },
747     { "classForName",           "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;",
748         Dalvik_java_lang_Class_classForName },
749     { "getClassLoader",         "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",
750         Dalvik_java_lang_Class_getClassLoader },
751     { "getComponentType",       "()Ljava/lang/Class;",
752         Dalvik_java_lang_Class_getComponentType },
753     { "getSignatureAnnotation",  "()[Ljava/lang/Object;",
754         Dalvik_java_lang_Class_getSignatureAnnotation },
755     { "getDeclaredClasses",     "(Ljava/lang/Class;Z)[Ljava/lang/Class;",
756         Dalvik_java_lang_Class_getDeclaredClasses },
757     { "getDeclaredConstructors", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;",
758         Dalvik_java_lang_Class_getDeclaredConstructors },
759     { "getDeclaredFields",      "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;",
760         Dalvik_java_lang_Class_getDeclaredFields },
761     { "getDeclaredMethods",     "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",
762         Dalvik_java_lang_Class_getDeclaredMethods },
763     { "getDeclaredConstructorOrMethod", "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;",
764         Dalvik_java_lang_Class_getDeclaredConstructorOrMethod },
765     { "getInterfaces",          "()[Ljava/lang/Class;",
766         Dalvik_java_lang_Class_getInterfaces },
767     { "getModifiers",           "(Ljava/lang/Class;Z)I",
768         Dalvik_java_lang_Class_getModifiers },
769     { "getNameNative",                "()Ljava/lang/String;",
770         Dalvik_java_lang_Class_getNameNative },
771     { "getSuperclass",          "()Ljava/lang/Class;",
772         Dalvik_java_lang_Class_getSuperclass },
773     { "isAssignableFrom",       "(Ljava/lang/Class;)Z",
774         Dalvik_java_lang_Class_isAssignableFrom },
775     { "isInstance",             "(Ljava/lang/Object;)Z",
776         Dalvik_java_lang_Class_isInstance },
777     { "isInterface",            "()Z",
778         Dalvik_java_lang_Class_isInterface },
779     { "isPrimitive",            "()Z",
780         Dalvik_java_lang_Class_isPrimitive },
781     { "newInstanceImpl",        "()Ljava/lang/Object;",
782         Dalvik_java_lang_Class_newInstance },
783     { "getDeclaringClass",      "()Ljava/lang/Class;",
784         Dalvik_java_lang_Class_getDeclaringClass },
785     { "getEnclosingClass",      "()Ljava/lang/Class;",
786         Dalvik_java_lang_Class_getEnclosingClass },
787     { "getEnclosingConstructor", "()Ljava/lang/reflect/Constructor;",
788         Dalvik_java_lang_Class_getEnclosingConstructor },
789     { "getEnclosingMethod",     "()Ljava/lang/reflect/Method;",
790         Dalvik_java_lang_Class_getEnclosingMethod },
791 #if 0
792     { "getGenericInterfaces",   "()[Ljava/lang/reflect/Type;",
793         Dalvik_java_lang_Class_getGenericInterfaces },
794     { "getGenericSuperclass",   "()Ljava/lang/reflect/Type;",
795         Dalvik_java_lang_Class_getGenericSuperclass },
796     { "getTypeParameters",      "()Ljava/lang/reflect/TypeVariable;",
797         Dalvik_java_lang_Class_getTypeParameters },
798 #endif
799     { "isAnonymousClass",       "()Z",
800         Dalvik_java_lang_Class_isAnonymousClass },
801     { "getDeclaredAnnotations", "()[Ljava/lang/annotation/Annotation;",
802         Dalvik_java_lang_Class_getDeclaredAnnotations },
803     { "getInnerClassName",       "()Ljava/lang/String;",
804         Dalvik_java_lang_Class_getInnerClassName },
805     { "setAccessibleNoCheck",   "(Ljava/lang/reflect/AccessibleObject;Z)V",
806         Dalvik_java_lang_Class_setAccessibleNoCheck },
807     { NULL, NULL, NULL },
808 };