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. 326 */ 327 static void Dalvik_java_lang_Class_getNameNative(const u4* args, JValue* pResult) 328 { 329 ClassObject* clazz = (ClassObject*) args[0]; 330 const char* descriptor = clazz->descriptor; 331 StringObject* nameObj; 332 333 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) { 334 /* 335 * The descriptor indicates that this is the class for 336 * a primitive type; special-case the return value. 337 */ 338 const char* name; 339 switch (descriptor[0]) { 340 case 'Z': name = "boolean"; break; 341 case 'B': name = "byte"; break; 342 case 'C': name = "char"; break; 343 case 'S': name = "short"; break; 344 case 'I': name = "int"; break; 345 case 'J': name = "long"; break; 346 case 'F': name = "float"; break; 347 case 'D': name = "double"; break; 348 case 'V': name = "void"; break; 349 default: { 350 LOGE("Unknown primitive type '%c'\n", descriptor[0]); 351 assert(false); 352 RETURN_PTR(NULL); 353 } 354 } 355 356 nameObj = dvmCreateStringFromCstr(name); 357 } else { 358 /* 359 * Convert the UTF-8 name to a java.lang.String. The 360 * name must use '.' to separate package components. 361 * 362 * TODO: this could be more efficient. Consider a custom 363 * conversion function here that walks the string once and 364 * avoids the allocation for the common case (name less than, 365 * say, 128 bytes). 366 */ 367 char* dotName = dvmDescriptorToDot(clazz->descriptor); 368 nameObj = dvmCreateStringFromCstr(dotName); 369 free(dotName); 370 } 371 372 dvmReleaseTrackedAlloc((Object*) nameObj, NULL); 373 374 #if 0 375 /* doesn't work -- need "java.lang.String" not "java/lang/String" */ 376 { 377 /* 378 * Find the string in the DEX file and use the copy in the intern 379 * table if it already exists (else put one there). Only works 380 * for strings in the DEX file, e.g. not arrays. 381 * 382 * We have to do the class lookup by name in the DEX file because 383 * we don't have a DexClassDef pointer in the ClassObject, and it's 384 * not worth adding one there just for this. Should be cheaper 385 * to do this than the string-creation above. 386 */ 387 const DexFile* pDexFile = clazz->pDexFile; 388 const DexClassDef* pClassDef; 389 const DexClassId* pClassId; 390 391 pDexFile = clazz->pDexFile; 392 pClassDef = dvmDexFindClass(pDexFile, clazz->descriptor); 393 pClassId = dvmDexGetClassId(pDexFile, pClassDef->classIdx); 394 nameObj = dvmDexGetResolvedString(pDexFile, pClassId->nameIdx); 395 if (nameObj == NULL) { 396 nameObj = dvmResolveString(clazz, pClassId->nameIdx); 397 if (nameObj == NULL) 398 LOGW("WARNING: couldn't find string %u for '%s'\n", 399 pClassId->nameIdx, clazz->name); 400 } 401 } 402 #endif 403 404 RETURN_PTR(nameObj); 405 } 406 407 /* 408 * Return the superclass for instances of this class. 409 * 410 * If the class represents a java/lang/Object, an interface, a primitive 411 * type, or void (which *is* a primitive type??), return NULL. 412 * 413 * For an array, return the java/lang/Object ClassObject. 414 */ 415 static void Dalvik_java_lang_Class_getSuperclass(const u4* args, 416 JValue* pResult) 417 { 418 ClassObject* clazz = (ClassObject*) args[0]; 419 420 if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz)) 421 RETURN_PTR(NULL); 422 else 423 RETURN_PTR(clazz->super); 424 } 425 426 /* 427 * public boolean isAssignableFrom(Class<?> cls) 428 * 429 * Determine if this class is either the same as, or is a superclass or 430 * superinterface of, the class specified in the "cls" parameter. 431 */ 432 static void Dalvik_java_lang_Class_isAssignableFrom(const u4* args, 433 JValue* pResult) 434 { 435 ClassObject* thisPtr = (ClassObject*) args[0]; 436 ClassObject* testClass = (ClassObject*) args[1]; 437 438 if (testClass == NULL) { 439 dvmThrowException("Ljava/lang/NullPointerException;", NULL); 440 RETURN_INT(false); 441 } 442 RETURN_INT(dvmInstanceof(testClass, thisPtr)); 443 } 444 445 /* 446 * public boolean isInstance(Object o) 447 * 448 * Dynamic equivalent of Java programming language "instanceof". 449 */ 450 static void Dalvik_java_lang_Class_isInstance(const u4* args, 451 JValue* pResult) 452 { 453 ClassObject* thisPtr = (ClassObject*) args[0]; 454 Object* testObj = (Object*) args[1]; 455 456 if (testObj == NULL) 457 RETURN_INT(false); 458 RETURN_INT(dvmInstanceof(testObj->clazz, thisPtr)); 459 } 460 461 /* 462 * public boolean isInterface() 463 */ 464 static void Dalvik_java_lang_Class_isInterface(const u4* args, 465 JValue* pResult) 466 { 467 ClassObject* thisPtr = (ClassObject*) args[0]; 468 469 RETURN_INT(dvmIsInterfaceClass(thisPtr)); 470 } 471 472 /* 473 * public boolean isPrimitive() 474 */ 475 static void Dalvik_java_lang_Class_isPrimitive(const u4* args, 476 JValue* pResult) 477 { 478 ClassObject* thisPtr = (ClassObject*) args[0]; 479 480 RETURN_INT(dvmIsPrimitiveClass(thisPtr)); 481 } 482 483 /* 484 * public T newInstance() throws InstantiationException, IllegalAccessException 485 * 486 * Create a new instance of this class. 487 */ 488 static void Dalvik_java_lang_Class_newInstance(const u4* args, JValue* pResult) 489 { 490 Thread* self = dvmThreadSelf(); 491 ClassObject* clazz = (ClassObject*) args[0]; 492 Method* init; 493 Object* newObj; 494 495 /* can't instantiate these */ 496 if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz) 497 || dvmIsArrayClass(clazz) || dvmIsAbstractClass(clazz)) 498 { 499 LOGD("newInstance failed: p%d i%d [%d a%d\n", 500 dvmIsPrimitiveClass(clazz), dvmIsInterfaceClass(clazz), 501 dvmIsArrayClass(clazz), dvmIsAbstractClass(clazz)); 502 dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationException;", 503 clazz->descriptor); 504 RETURN_VOID(); 505 } 506 507 /* initialize the class if it hasn't been already */ 508 if (!dvmIsClassInitialized(clazz)) { 509 if (!dvmInitClass(clazz)) { 510 LOGW("Class init failed in newInstance call (%s)\n", 511 clazz->descriptor); 512 assert(dvmCheckException(self)); 513 RETURN_VOID(); 514 } 515 } 516 517 /* find the "nullary" constructor */ 518 init = dvmFindDirectMethodByDescriptor(clazz, "<init>", "()V"); 519 if (init == NULL) { 520 /* common cause: secret "this" arg on non-static inner class ctor */ 521 LOGD("newInstance failed: no <init>()\n"); 522 dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationException;", 523 clazz->descriptor); 524 RETURN_VOID(); 525 } 526 527 /* 528 * Verify access from the call site. 529 * 530 * First, make sure the method invoking Class.newInstance() has permission 531 * to access the class. 532 * 533 * Second, make sure it has permission to invoke the constructor. The 534 * constructor must be public or, if the caller is in the same package, 535 * have package scope. 536 */ 537 ClassObject* callerClass = dvmGetCaller2Class(self->curFrame); 538 539 if (!dvmCheckClassAccess(callerClass, clazz)) { 540 LOGD("newInstance failed: %s not accessible to %s\n", 541 clazz->descriptor, callerClass->descriptor); 542 dvmThrowException("Ljava/lang/IllegalAccessException;", 543 "access to class not allowed"); 544 RETURN_VOID(); 545 } 546 if (!dvmCheckMethodAccess(callerClass, init)) { 547 LOGD("newInstance failed: %s.<init>() not accessible to %s\n", 548 clazz->descriptor, callerClass->descriptor); 549 dvmThrowException("Ljava/lang/IllegalAccessException;", 550 "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 */ 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 */ 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 */ 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 */ 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 */ 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 dvmThrowException("Ljava/lang/UnsupportedOperationException;", 656 "native method not implemented"); 657 658 RETURN_PTR(NULL); 659 } 660 661 static void Dalvik_java_lang_Class_getGenericSuperclass(const u4* args, 662 JValue* pResult) 663 { 664 dvmThrowException("Ljava/lang/UnsupportedOperationException;", 665 "native method not implemented"); 666 667 RETURN_PTR(NULL); 668 } 669 670 static void Dalvik_java_lang_Class_getTypeParameters(const u4* args, 671 JValue* pResult) 672 { 673 dvmThrowException("Ljava/lang/UnsupportedOperationException;", 674 "native method not implemented"); 675 676 RETURN_PTR(NULL); 677 } 678 #endif 679 680 /* 681 * public boolean isAnonymousClass() 682 * 683 * Returns true if this is an "anonymous" class. 684 */ 685 static void Dalvik_java_lang_Class_isAnonymousClass(const u4* args, 686 JValue* pResult) 687 { 688 ClassObject* clazz = (ClassObject*) args[0]; 689 StringObject* className = NULL; 690 int accessFlags; 691 692 /* 693 * If this has an InnerClass annotation, pull it out. Lack of the 694 * annotation, or an annotation with a NULL class name, indicates 695 * that this is an anonymous inner class. 696 */ 697 if (!dvmGetInnerClass(clazz, &className, &accessFlags)) 698 RETURN_BOOLEAN(false); 699 700 dvmReleaseTrackedAlloc((Object*) className, NULL); 701 RETURN_BOOLEAN(className == NULL); 702 } 703 704 /* 705 * private Annotation[] getDeclaredAnnotations() 706 * 707 * Return the annotations declared on this class. 708 */ 709 static void Dalvik_java_lang_Class_getDeclaredAnnotations(const u4* args, 710 JValue* pResult) 711 { 712 ClassObject* clazz = (ClassObject*) args[0]; 713 714 ArrayObject* annos = dvmGetClassAnnotations(clazz); 715 dvmReleaseTrackedAlloc((Object*) annos, NULL); 716 RETURN_PTR(annos); 717 } 718 719 /* 720 * public String getInnerClassName() 721 * 722 * Returns the simple name of a member class or local class, or null otherwise. 723 */ 724 static void Dalvik_java_lang_Class_getInnerClassName(const u4* args, 725 JValue* pResult) 726 { 727 ClassObject* clazz = (ClassObject*) args[0]; 728 StringObject* nameObj; 729 int flags; 730 731 if (dvmGetInnerClass(clazz, &nameObj, &flags)) { 732 dvmReleaseTrackedAlloc((Object*) nameObj, NULL); 733 RETURN_PTR(nameObj); 734 } else { 735 RETURN_PTR(NULL); 736 } 737 } 738 739 /* 740 * static native void setAccessibleNoCheck(AccessibleObject ao, boolean flag); 741 */ 742 static void Dalvik_java_lang_Class_setAccessibleNoCheck(const u4* args, 743 JValue* pResult) 744 { 745 Object* target = (Object*) args[0]; 746 u4 flag = (u4) args[1]; 747 748 dvmSetFieldBoolean(target, gDvm.offJavaLangReflectAccessibleObject_flag, 749 flag); 750 } 751 752 const DalvikNativeMethod dvm_java_lang_Class[] = { 753 { "desiredAssertionStatus", "()Z", 754 Dalvik_java_lang_Class_desiredAssertionStatus }, 755 { "classForName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;", 756 Dalvik_java_lang_Class_classForName }, 757 { "getClassLoader", "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", 758 Dalvik_java_lang_Class_getClassLoader }, 759 { "getComponentType", "()Ljava/lang/Class;", 760 Dalvik_java_lang_Class_getComponentType }, 761 { "getSignatureAnnotation", "()[Ljava/lang/Object;", 762 Dalvik_java_lang_Class_getSignatureAnnotation }, 763 { "getDeclaredClasses", "(Ljava/lang/Class;Z)[Ljava/lang/Class;", 764 Dalvik_java_lang_Class_getDeclaredClasses }, 765 { "getDeclaredConstructors", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;", 766 Dalvik_java_lang_Class_getDeclaredConstructors }, 767 { "getDeclaredFields", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;", 768 Dalvik_java_lang_Class_getDeclaredFields }, 769 { "getDeclaredMethods", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;", 770 Dalvik_java_lang_Class_getDeclaredMethods }, 771 { "getInterfaces", "()[Ljava/lang/Class;", 772 Dalvik_java_lang_Class_getInterfaces }, 773 { "getModifiers", "(Ljava/lang/Class;Z)I", 774 Dalvik_java_lang_Class_getModifiers }, 775 { "getNameNative", "()Ljava/lang/String;", 776 Dalvik_java_lang_Class_getNameNative }, 777 { "getSuperclass", "()Ljava/lang/Class;", 778 Dalvik_java_lang_Class_getSuperclass }, 779 { "isAssignableFrom", "(Ljava/lang/Class;)Z", 780 Dalvik_java_lang_Class_isAssignableFrom }, 781 { "isInstance", "(Ljava/lang/Object;)Z", 782 Dalvik_java_lang_Class_isInstance }, 783 { "isInterface", "()Z", 784 Dalvik_java_lang_Class_isInterface }, 785 { "isPrimitive", "()Z", 786 Dalvik_java_lang_Class_isPrimitive }, 787 { "newInstanceImpl", "()Ljava/lang/Object;", 788 Dalvik_java_lang_Class_newInstance }, 789 { "getDeclaringClass", "()Ljava/lang/Class;", 790 Dalvik_java_lang_Class_getDeclaringClass }, 791 { "getEnclosingClass", "()Ljava/lang/Class;", 792 Dalvik_java_lang_Class_getEnclosingClass }, 793 { "getEnclosingConstructor", "()Ljava/lang/reflect/Constructor;", 794 Dalvik_java_lang_Class_getEnclosingConstructor }, 795 { "getEnclosingMethod", "()Ljava/lang/reflect/Method;", 796 Dalvik_java_lang_Class_getEnclosingMethod }, 797 #if 0 798 { "getGenericInterfaces", "()[Ljava/lang/reflect/Type;", 799 Dalvik_java_lang_Class_getGenericInterfaces }, 800 { "getGenericSuperclass", "()Ljava/lang/reflect/Type;", 801 Dalvik_java_lang_Class_getGenericSuperclass }, 802 { "getTypeParameters", "()Ljava/lang/reflect/TypeVariable;", 803 Dalvik_java_lang_Class_getTypeParameters }, 804 #endif 805 { "isAnonymousClass", "()Z", 806 Dalvik_java_lang_Class_isAnonymousClass }, 807 { "getDeclaredAnnotations", "()[Ljava/lang/annotation/Annotation;", 808 Dalvik_java_lang_Class_getDeclaredAnnotations }, 809 { "getInnerClassName", "()Ljava/lang/String;", 810 Dalvik_java_lang_Class_getInnerClassName }, 811 { "setAccessibleNoCheck", "(Ljava/lang/reflect/AccessibleObject;Z)V", 812 Dalvik_java_lang_Class_setAccessibleNoCheck }, 813 { NULL, NULL, NULL }, 814 }; 815