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