jboolean Java_java_lang_Class_isAssignableFrom(Env* env, Class* thiz, Class* that) { if (!that) { rvmThrowNullPointerException(env); return FALSE; } return rvmIsAssignableFrom(env, that, thiz); }
jboolean rvmIsAssignableFrom(Env* env, Class* s, Class* t) { // TODO: What if s or t are NULL? if (s == t || t == java_lang_Object) { return TRUE; } if (CLASS_IS_ARRAY(s)) { if (t == java_io_Serializable) { return TRUE; } if (t == java_lang_Cloneable) { return TRUE; } if (!CLASS_IS_ARRAY(t)) { return FALSE; } Class* componentType = s->componentType; if (CLASS_IS_PRIMITIVE(componentType)) { // s is a primitive array and can only be assigned to // class t if s == t or t == (Object|Serializable|Cloneable). But we // already know that s != t and t != (Object|Serializable|Cloneable) return FALSE; } return rvmIsAssignableFrom(env, componentType, t->componentType); } if (CLASS_IS_INTERFACE(t)) { // s or any of its parents must implement the interface t for (; s; s = s->superclass) { Interface* interface = rvmGetInterfaces(env, s); if (rvmExceptionCheck(env)) return FALSE; for (; interface != NULL; interface = interface->next) { if (rvmIsAssignableFrom(env, interface->interface, t)) { return TRUE; } } } return FALSE; } while (s && s != t) { s = s->superclass; } return s ? TRUE : FALSE; }
Object* _bcCheckcastArray(Env* env, Class* arrayClass, Object* o) { if (!o) return o; ENTER; jboolean b = rvmIsAssignableFrom(env, o->clazz, arrayClass); if (!rvmExceptionCheck(env) && !b) { rvmThrowClassCastException(env, arrayClass, o->clazz); } LEAVE(o); }
Object* _bcCheckcast(Env* env, ClassInfoHeader* header, Object* o) { if (!o) return o; ENTER; Class* clazz = ldcClass(env, header); if (clazz) { jboolean b = rvmIsAssignableFrom(env, o->clazz, clazz); if (!rvmExceptionCheck(env) && !b) { rvmThrowClassCastException(env, clazz, o->clazz); } } LEAVE(o); }
void _bcSetObjectArrayElement(Env* env, ObjectArray* array, jint index, Object* value) { if (!value) { array->values[index] = value; return; } ENTER; Class* componentType = array->object.clazz->componentType; jboolean assignable = rvmIsAssignableFrom(env, value->clazz, componentType); if (!rvmExceptionCheck(env) && !assignable) { rvmThrowArrayStoreException(env, value->clazz, array->object.clazz); } if (!rvmExceptionCheck(env)) array->values[index] = value; LEAVEV; }
static jboolean IsAssignableFrom(JNIEnv* env, jclass sub, jclass sup) { return rvmIsAssignableFrom((Env*) env, (Class*) sub, (Class*) sup); }
jboolean rvmIsInstanceOf(Env* env, Object* obj, Class* clazz) { if (!obj) return FALSE; return rvmIsAssignableFrom(env, obj->clazz, clazz); }