/* * Show a relatively human-readable message describing the failure to * resolve a class. * * TODO: this is somewhat misleading when resolution fails because of * illegal access rather than nonexistent class. */ void dvmLogUnableToResolveClass(const char *missingClassDescr, const Method *meth) { if (gDvm.optimizing) { return; } std::string dotMissingClass = dvmHumanReadableDescriptor(missingClassDescr); std::string dotFromClass = dvmHumanReadableDescriptor(meth->clazz->descriptor); ALOGE("Could not find class '%s', referenced from method %s.%s", dotMissingClass.c_str(), dotFromClass.c_str(), meth->name); }
std::string dvmHumanReadableType(const Object* obj) { if (obj == NULL) { return "null"; } if (obj->clazz == NULL) { /* should only be possible right after a plain dvmMalloc() */ return "(raw)"; } std::string result(dvmHumanReadableDescriptor(obj->clazz->descriptor)); if (dvmIsClassObject(obj)) { const ClassObject* clazz = reinterpret_cast<const ClassObject*>(obj); result += "<" + dvmHumanReadableDescriptor(clazz->descriptor) + ">"; } return result; }
TEST(dvmHumanReadableDescriptor, PrimitiveScalars) { ASSERT_EQ("boolean", dvmHumanReadableDescriptor("Z")); ASSERT_EQ("byte", dvmHumanReadableDescriptor("B")); ASSERT_EQ("char", dvmHumanReadableDescriptor("C")); ASSERT_EQ("double", dvmHumanReadableDescriptor("D")); ASSERT_EQ("float", dvmHumanReadableDescriptor("F")); ASSERT_EQ("int", dvmHumanReadableDescriptor("I")); ASSERT_EQ("long", dvmHumanReadableDescriptor("J")); ASSERT_EQ("short", dvmHumanReadableDescriptor("S")); }
std::string dvmHumanReadableField(const Field* field) { if (field == NULL) { return "(null)"; } std::string result(dvmHumanReadableDescriptor(field->clazz->descriptor)); result += '.'; result += field->name; return result; }
std::string dvmHumanReadableMethod(const Method* method, bool withSignature) { if (method == NULL) { return "(null)"; } std::string result(dvmHumanReadableDescriptor(method->clazz->descriptor)); result += '.'; result += method->name; if (withSignature) { // TODO: the types in this aren't human readable! char* signature = dexProtoCopyMethodDescriptor(&method->prototype); result += signature; free(signature); } return result; }
/* * Verify that "obj" is non-null and is an instance of "clazz". * Used to implement reflection on fields and methods. * * Returns "false" and throws an exception if not. */ bool dvmVerifyObjectInClass(Object* obj, ClassObject* clazz) { ClassObject* exceptionClass = NULL; if (obj == NULL) { exceptionClass = gDvm.exNullPointerException; } else if (!dvmInstanceof(obj->clazz, clazz)) { exceptionClass = gDvm.exIllegalArgumentException; } if (exceptionClass == NULL) { return true; } std::string expectedClassName(dvmHumanReadableDescriptor(clazz->descriptor)); std::string actualClassName(dvmHumanReadableType(obj)); dvmThrowExceptionFmt(exceptionClass, "expected receiver of type %s, but got %s", expectedClassName.c_str(), actualClassName.c_str()); return false; }
static void throwArgumentTypeMismatch(int argIndex, ClassObject* expected, DataObject* arg) { std::string expectedClassName(dvmHumanReadableDescriptor(expected->descriptor)); std::string actualClassName = dvmHumanReadableType(arg); dvmThrowExceptionFmt(gDvm.exIllegalArgumentException, "argument %d should have type %s, got %s", argIndex + 1, expectedClassName.c_str(), actualClassName.c_str()); }
/* *bref:获取class的id. */ static int getPrettyClassNameId(const char *descriptor) { std::string name(dvmHumanReadableDescriptor(descriptor)); return hprofLookupStringId(name.c_str()); }
TEST(dvmHumanReadableDescriptor, ScalarReferences) { ASSERT_EQ("java.lang.String", dvmHumanReadableDescriptor("Ljava.lang.String;")); ASSERT_EQ("java.lang.String", dvmHumanReadableDescriptor("Ljava/lang/String;")); }
TEST(dvmHumanReadableDescriptor, ArrayReferences) { ASSERT_EQ("java.lang.Class[]", dvmHumanReadableDescriptor("[Ljava/lang/Class;")); ASSERT_EQ("java.lang.Class[][]", dvmHumanReadableDescriptor("[[Ljava/lang/Class;")); }
TEST(dvmHumanReadableDescriptor, PrimitiveArrays) { ASSERT_EQ("boolean[]", dvmHumanReadableDescriptor("[Z")); ASSERT_EQ("boolean[][]", dvmHumanReadableDescriptor("[[Z")); ASSERT_EQ("byte[]", dvmHumanReadableDescriptor("[B")); ASSERT_EQ("byte[][]", dvmHumanReadableDescriptor("[[B")); ASSERT_EQ("char[]", dvmHumanReadableDescriptor("[C")); ASSERT_EQ("char[][]", dvmHumanReadableDescriptor("[[C")); ASSERT_EQ("double[]", dvmHumanReadableDescriptor("[D")); ASSERT_EQ("double[][]", dvmHumanReadableDescriptor("[[D")); ASSERT_EQ("float[]", dvmHumanReadableDescriptor("[F")); ASSERT_EQ("float[][]", dvmHumanReadableDescriptor("[[F")); ASSERT_EQ("int[]", dvmHumanReadableDescriptor("[I")); ASSERT_EQ("int[][]", dvmHumanReadableDescriptor("[[I")); ASSERT_EQ("long[]", dvmHumanReadableDescriptor("[J")); ASSERT_EQ("long[][]", dvmHumanReadableDescriptor("[[J")); ASSERT_EQ("short[]", dvmHumanReadableDescriptor("[S")); ASSERT_EQ("short[][]", dvmHumanReadableDescriptor("[[S")); }