📄 pool.c
字号:
} thisClass = thisEntry->clazz; if (IS_ARRAY_CLASS(thisClass)) { loadArrayClass((ARRAY_CLASS)thisClass); } else if (((INSTANCE_CLASS)thisClass)->status == CLASS_RAW) { loadClassfile((INSTANCE_CLASS)thisClass, TRUE); } verifyClassAccess(thisClass, currentClass); cachePoolEntry(constantPool, cpIndex, (cell*)thisClass); return thisClass;}/*========================================================================= * FUNCTION: resolveFieldReference() * TYPE: public instance-level operation * OVERVIEW: Given an index to a CONSTANT_Fieldref, get the Field * that the index refers to. * INTERFACE: * parameters: constant pool pointer, constant pool index, isStatic * returns: field pointer *=======================================================================*/FIELD resolveFieldReference(CONSTANTPOOL constantPool, unsigned int cpIndex, bool_t isStatic, int opcode, INSTANCE_CLASS currentClass) { CONSTANTPOOL_ENTRY thisEntry = &constantPool->entries[cpIndex]; unsigned char thisTag = CONSTANTPOOL_TAG(constantPool, cpIndex); FIELD thisField; CLASS thisClass; if (thisTag & CP_CACHEBIT) { /* Check if this entry has already been resolved (cached) */ /* If so, simply return the earlier resolved class */ thisField = (FIELD)(thisEntry->cache); } else { unsigned short classIndex = thisEntry->method.classIndex; unsigned short nameTypeIndex = thisEntry->method.nameTypeIndex; NameTypeKey nameTypeKey = constantPool->entries[nameTypeIndex].nameTypeKey; thisClass = resolveClassReference(constantPool, classIndex, currentClass); thisField = NULL; if ( !IS_ARRAY_CLASS(thisClass) && (((INSTANCE_CLASS)thisClass)->status != CLASS_ERROR)) { thisField = lookupField((INSTANCE_CLASS)thisClass, nameTypeKey); } } /* Cache the value */ if (thisField != NULL) { if (isStatic ? ((thisField->accessFlags & ACC_STATIC) == 0) : ((thisField->accessFlags & ACC_STATIC) != 0)) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(char *, fieldClassName, getClassName((CLASS)(thisField->ofClass))); sprintf(str_buffer, KVM_MSG_INCOMPATIBLE_CLASS_CHANGE_2STRPARAMS, fieldClassName, fieldName(thisField)); fatalVMError(str_buffer); END_TEMPORARY_ROOTS } if ((thisField->accessFlags & ACC_FINAL) && (opcode == PUTSTATIC || opcode == PUTFIELD) && (thisField->ofClass != currentClass)) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(char *, fieldClassName, getClassName((CLASS)(thisField->ofClass))); DECLARE_TEMPORARY_ROOT(char *, currentClassName, getClassName((CLASS)currentClass)); sprintf(str_buffer, KVM_MSG_CANNOT_MODIFY_FINAL_FIELD_3STRPARAMS, fieldClassName, fieldName(thisField), currentClassName); END_TEMPORARY_ROOTS fatalError(str_buffer); } if (!(thisTag & CP_CACHEBIT)) { /* Since access only depends on the class, and not on the * specific byte code used to access the field, we don't need * to perform this check if the constant pool entry * has already been resolved. */ if (!classHasAccessToMember(currentClass, thisField->accessFlags, thisField->ofClass, (INSTANCE_CLASS)thisClass)) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(char *, fieldClassName, getClassName((CLASS)(thisField->ofClass))); DECLARE_TEMPORARY_ROOT(char *, currentClassName, getClassName((CLASS)currentClass)); sprintf(str_buffer, KVM_MSG_CANNOT_ACCESS_MEMBER_FROM_CLASS_3STRPARAMS, fieldClassName, fieldName(thisField), currentClassName); END_TEMPORARY_ROOTS fatalError(str_buffer); } cachePoolEntry(constantPool, cpIndex, (cell*)thisField); } } return thisField;}/*========================================================================= * FUNCTION: resolveMethodReference() * TYPE: public instance-level operation * OVERVIEW: Given an index to a CONSTANT_Methodref or * CONSTANT_InterfaceMethodref, get the Method * that the index refers to. * INTERFACE: * parameters: constant pool pointer, constant pool index * returns: method pointer *=======================================================================*/METHOD resolveMethodReference(CONSTANTPOOL constantPool, unsigned int cpIndex, bool_t isStatic, INSTANCE_CLASS currentClass) { CONSTANTPOOL_ENTRY thisEntry = &constantPool->entries[cpIndex]; unsigned char thisTag = CONSTANTPOOL_TAG(constantPool, cpIndex); if (thisTag & CP_CACHEBIT) { /* Check if this entry has already been resolved (cached) */ /* If so, simply return the earlier resolved class */ return (METHOD)(thisEntry->cache); } else { unsigned short classIndex = thisEntry->method.classIndex; unsigned short nameTypeIndex = thisEntry->method.nameTypeIndex; CLASS thisClass = resolveClassReference(constantPool, classIndex, currentClass); NameTypeKey nameTypeKey; METHOD thisMethod = NULL; if ( (((thisTag & CP_CACHEMASK) == CONSTANT_InterfaceMethodref) && !(thisClass->accessFlags & ACC_INTERFACE)) || (((thisTag & CP_CACHEMASK) == CONSTANT_Methodref) && (thisClass->accessFlags & ACC_INTERFACE))) { /* "Bad methodref" */ fatalError(KVM_MSG_BAD_FIELD_OR_METHOD_REFERENCE); } nameTypeKey = constantPool->entries[nameTypeIndex].nameTypeKey; if (IS_ARRAY_CLASS(thisClass) || ((INSTANCE_CLASS)thisClass)->status != CLASS_ERROR) { thisMethod = lookupMethod(thisClass, nameTypeKey, currentClass); if (nameTypeKey.nt.nameKey == initNameAndType.nt.nameKey) { if (thisMethod != NULL && thisMethod->ofClass != (INSTANCE_CLASS)thisClass) { thisMethod = NULL; } } } if (thisMethod) { if (isStatic ? ((thisMethod->accessFlags & ACC_STATIC) == 0) : ((thisMethod->accessFlags & ACC_STATIC) != 0)) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(char*, methodClassName, getClassName((CLASS)thisMethod->ofClass)); DECLARE_TEMPORARY_ROOT(char*, methodSignature, getMethodSignature(thisMethod)); sprintf(str_buffer, KVM_MSG_INCOMPATIBLE_CLASS_CHANGE_3STRPARAMS, methodClassName, methodName(thisMethod), methodSignature); fatalVMError(str_buffer); END_TEMPORARY_ROOTS } if (!classHasAccessToMember(currentClass, thisMethod->accessFlags, thisMethod->ofClass, (INSTANCE_CLASS)thisClass)) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(char*, className, getClassName((CLASS)currentClass)); DECLARE_TEMPORARY_ROOT(char*, methodClassName, getClassName((CLASS)thisMethod->ofClass)); sprintf(str_buffer, KVM_MSG_CANNOT_ACCESS_MEMBER_FROM_CLASS_3STRPARAMS, methodClassName, methodName(thisMethod), className); END_TEMPORARY_ROOTS fatalError(str_buffer); } cachePoolEntry(constantPool, cpIndex, (cell*)thisMethod); } else { /* Some appropriate error message in debug mode */ } return thisMethod; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -