📄 verify-type.c
字号:
{ SupertypeSet* l; while (supertypes) { l = supertypes->next; gc_free(supertypes->list); gc_free(supertypes); supertypes = l; }}/* * merges two types, t1 and t2, into t2. * if t1 and t2 cannot be merged, t2 will become TUNSTABLE. * merging may result in t2 being represented as a supertype list. * * @return whether an actual merger was made (i.e. they two types given were not the same type) */boolmergeTypes(Verifier* v, Type* t1, Type* t2){ if (IS_ADDRESS(t1) || IS_ADDRESS(t2)) { /* if one of the types is TADDR, the other one must also be TADDR */ if (t1->tinfo != t2->tinfo) { return false; } /* TODO: should this be an error if they don't agree? */ t2->tinfo = t1->tinfo; return true; } else if (t2->data.class == TUNSTABLE->data.class || sameType(t1, t2)) { return false; } else if (t1->tinfo & TINFO_UNINIT || t2->tinfo & TINFO_UNINIT || !isReference(t1) || !isReference(t2)) { *t2 = *TUNSTABLE; return true; } /* references only from here on out. * must resolve them to go on */ resolveType(v, t1); resolveType(v, t2); if ((t1->tinfo & TINFO_CLASS && t1->data.class == NULL) || (t2->tinfo & TINFO_CLASS && t2->data.class == NULL)) { return false; } /* at this point, t1 and t2 are either TINFO_CLASS or * TINFO_SUPERTYPES */ if (t1->tinfo & TINFO_SUPERTYPES) { if (t2->tinfo & TINFO_SUPERTYPES) mergeSupersets(v, t1, t2); else mergeClassAndSuperset(v, t2, t1); } else if (t2->tinfo & TINFO_SUPERTYPES) { mergeClassAndSuperset(v, t1, t2); } else { /* both are TINFO_CLASS */ if (instanceof(t1->data.class, t2->data.class)) { *t2 = *t1; return true; } else if (instanceof(t2->data.class, t1->data.class)) { return false; } else { DBG(VERIFY3, dprintf("HERE\n"); ); mergeClassesIntoSuperset(v, t1, t2); } } if (v->supertypes->count == 1) { t2->tinfo = TINFO_CLASS; t2->data.class = v->supertypes->list[0]; } else { t2->tinfo = TINFO_SUPERTYPES; t2->data.supertypes = v->supertypes; } return true;}/* * returns the first (highest) common superclass of classes A and B. * * precondition: neither type is an array type * nor is either a primitive type */Hjava_lang_Class*getCommonSuperclass(Hjava_lang_Class* t1, Hjava_lang_Class* t2){ Hjava_lang_Class* A; Hjava_lang_Class* B; for (A = t1; A != NULL; A = A->superclass) { for (B = t2; B != NULL; B = B->superclass) { if (A == B) return A; } } /* error of some kind...at the very least, we shoulda gotten to Object * when traversing the class hirearchy */ return TUNSTABLE->data.class;}/* * @return true if the type is a reference type */boolisReference(const Type* t){ return (t->tinfo & TINFO_NAME || t->tinfo & TINFO_SIG || t->tinfo & TINFO_CLASS || t->tinfo & TINFO_UNINIT || t->tinfo & TINFO_SUPERTYPES);}/* * isArray() * returns whether the Type is an array Type */boolisArray(const Type* t){ if (!isReference(t)) { return false; } else if (t->tinfo & TINFO_NAME || t->tinfo & TINFO_SIG) { return (*(t->data.sig) == '['); } else if (t->tinfo & TINFO_SUPERTYPES) { /* if one of the supertypes is an array, it follows that * all supertypes in the list must be arrays */ return ((*CLASS_CNAME(t->data.supertypes->list[0])) == '['); } else if (t->tinfo != TINFO_CLASS) { return false; } else { return (*(CLASS_CNAME(t->data.class)) == '['); }}/* * sameType() * returns whether two Types are effectively equivalent. */boolsameType(Type* t1, Type* t2){ switch (t1->tinfo) { case TINFO_SYSTEM: return (t2->tinfo == TINFO_SYSTEM && t1->data.class == t2->data.class); case TINFO_ADDR: return (t2->tinfo == TINFO_ADDR && t1->data.addr == t2->data.addr); case TINFO_PRIMITIVE: return (t2->tinfo == TINFO_PRIMITIVE && t1->data.class == t2->data.class); case TINFO_UNINIT: case TINFO_UNINIT_SUPER: return (t2->tinfo & TINFO_UNINIT && (t1->data.uninit == t2->data.uninit || sameRefType(&(t1->data.uninit->type), &(t2->data.uninit->type)))); case TINFO_SUPERTYPES: { uint32 i; if (t2->tinfo != TINFO_SUPERTYPES || t1->data.supertypes->count != t2->data.supertypes->count) { return false; } else if (t1->data.supertypes == t2->data.supertypes) { return true; } for (i = 0; i < t1->data.supertypes->count; i++) { if (t1->data.supertypes->list[i] != t2->data.supertypes->list[i]) return false; } return true; } default: DBG(VERIFY3, dprintf("%ssameType(): unrecognized tinfo (%d)\n", indent, t1->tinfo); ); return false; case TINFO_SIG: case TINFO_NAME: case TINFO_CLASS: return ((t2->tinfo == TINFO_SIG || t2->tinfo == TINFO_NAME || t2->tinfo == TINFO_CLASS) && sameRefType(t1,t2)); }}/* * sameRefType() * returns whether two Types are effectively equivalent. * * pre: t1 and t2 are both reference types */boolsameRefType(Type* t1, Type* t2){ const char* sig1 = NULL; const char* sig2 = NULL; uint32 len1, len2; if (isNull(t1) || isNull(t2)) { return true; } if (t1->tinfo & TINFO_NAME) { sig1 = t1->data.name; if (t2->tinfo & TINFO_NAME) { return (!strcmp(sig1, t2->data.name)); } else if (t2->tinfo & TINFO_SIG) { sig2 = t2->data.sig; len1 = strlen(sig1); len2 = strlen(sig2); sig2++; if ((len1 + 2 != len2) || strncmp(sig1, sig2, len1)) return false; } else { if (strcmp(sig1, CLASS_CNAME(t2->data.class))) return false; } *t1 = *t2; return true; } else if (t1->tinfo & TINFO_SIG) { sig1 = t1->data.sig; if (t2->tinfo & TINFO_SIG) { return (!strcmp(sig1, t2->data.sig)); } else if (t2->tinfo & TINFO_NAME) { sig2 = t2->data.name; len1 = strlen(sig1); len2 = strlen(sig2); sig1++; if ((len1 != len2 + 2) || strncmp(sig1, sig2, len2)) return false; *t2 = *t1; return true; } else { sig2 = CLASS_CNAME(t2->data.class); len1 = strlen(sig1); len2 = strlen(sig2); sig1++; if ((len1 != len2 + 2) || strncmp(sig1, sig2, len2)) return false; *t1 = *t2; return true; } } else { sig1 = CLASS_CNAME(t1->data.class); if (t2->tinfo & TINFO_SIG) { sig2 = t2->data.sig; len1 = strlen(sig1); len2 = strlen(sig2); sig2++; if ((len1 + 2 != len2) || strncmp(sig1, sig2, len1)) return false; *t2 = *t1; return true; } else if (t2->tinfo & TINFO_NAME) { sig2 = t2->data.name; if (strcmp(sig1, sig2)) return false; *t2 = *t1; return true; } else { /* we should never get here */ sig2 = CLASS_CNAME(t2->data.class); return (!strcmp(sig1, sig2)); } }}/** * Determines whether t2 can be used as a t1; that is, whether * t2 implements or inherits from t1. * * pre: t1 is NOT a supertype list. (i believe that this can't * happen right now. grep through the verifier sources to * confirm). * * @return whether t2 can be a t1. */booltypecheck(Verifier* v, Type* t1, Type* t2){ DBG(VERIFY3, dprintf("%stypechecking ", indent); printType(t1); dprintf(" vs. "); printType(t2); dprintf("\n"); ); if (sameType(t1, t2)) { return true; } else if (t1->tinfo & TINFO_UNINIT || t2->tinfo & TINFO_UNINIT) { return false; } else if (!isReference(t1) || !isReference(t2)) { return false; } else if (sameType(t1, TOBJ)) { return true; } else if (t1->tinfo & TINFO_SUPERTYPES) { /* we should never get this when type checking */ postExceptionMessage(v->einfo, JAVA_LANG(InternalError), "in typecheck(): doing method %s.%s", CLASS_CNAME(v->class), METHOD_NAMED(v->method)); return false; } resolveType(v, t1); if (t1->data.class == NULL) { return false; } if (t2->tinfo & TINFO_SUPERTYPES && CLASS_IS_INTERFACE(t1->data.class)) { uint32 i; SupertypeSet* s = t2->data.supertypes; if (instanceof(t1->data.class, s->list[0])) return true; for (i = 1; i < s->count; i++) { if (s->list[i] == t1->data.class) return true; } return false; } resolveType(v, t2); if (t2->data.class == NULL) { return false; } return instanceof(t1->data.class, t2->data.class);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -