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