📄 pool.c
字号:
/*0187*/ return thisClass;
/*0188*/}
/*0189*/
/*0190*//*=========================================================================
/*0191./ * FUNCTION: resolveFieldReference()
/*0192./ * TYPE: public instance-level operation
/*0193./ * OVERVIEW: Given an index to a CONSTANT_Fieldref, get the Field
/*0194./ * that the index refers to.
/*0195./ * INTERFACE:
/*0196./ * parameters: constant pool pointer, constant pool index, isStatic
/*0197./ * returns: field pointer
/*0198./ *=======================================================================*/
/*0199*/
/*0200*/FIELD resolveFieldReference(CONSTANTPOOL constantPool, unsigned int cpIndex,
/*0201*/ bool_t isStatic, int opcode,
/*0202*/ INSTANCE_CLASS currentClass) {
/*0203*/ CONSTANTPOOL_ENTRY thisEntry = &constantPool->entries[cpIndex];
/*0204*/ unsigned char thisTag = CONSTANTPOOL_TAG(constantPool, cpIndex);
/*0205*/ FIELD thisField;
/*0206*/
/*0207*/ if (thisTag & CP_CACHEBIT) {
/*0208*/ /* Check if this entry has already been resolved (cached) */
/*0209*/ /* If so, simply return the earlier resolved class */
/*0210*/
/*0211*/ thisField = (FIELD)(thisEntry->cache);
/*0212*/ } else {
/*0213*/ unsigned short classIndex = thisEntry->method.classIndex;
/*0214*/ unsigned short nameTypeIndex = thisEntry->method.nameTypeIndex;
/*0215*/
/*0216*/ CLASS thisClass = resolveClassReference(constantPool,
/*0217*/ classIndex,
/*0218*/ currentClass);
/*0219*/ NameTypeKey nameTypeKey =
/*0220*/ constantPool->entries[nameTypeIndex].nameTypeKey;
/*0221*/
/*0222*/ thisField = NULL;
/*0223*/ if ( !IS_ARRAY_CLASS(thisClass)
/*0224*/ && (((INSTANCE_CLASS)thisClass)->status != CLASS_ERROR)) {
/*0225*/ thisField = lookupField((INSTANCE_CLASS)thisClass, nameTypeKey);
/*0226*/ }
/*0227*/ }
/*0228*/
/*0229*/ /* Cache the value */
/*0230*/ if (thisField != NULL) {
/*0231*/ if (isStatic ? ((thisField->accessFlags & ACC_STATIC) == 0)
/*0232*/ : ((thisField->accessFlags & ACC_STATIC) != 0)) {
/*0233*/ START_TEMPORARY_ROOTS
/*0234*/ DECLARE_TEMPORARY_ROOT(char *, fieldClassName,
/*0235*/ getClassName((CLASS)(thisField->ofClass)));
/*0236*/ sprintf(str_buffer,
/*0237*/ KVM_MSG_INCOMPATIBLE_CLASS_CHANGE_2STRPARAMS,
/*0238*/ fieldClassName,
/*0239*/ fieldName(thisField));
/*0240*/ fatalVMError(str_buffer);
/*0241*/ END_TEMPORARY_ROOTS
/*0242*/ }
/*0243*/ if ((thisField->accessFlags & ACC_FINAL) &&
/*0244*/ (opcode == PUTSTATIC || opcode == PUTFIELD) &&
/*0245*/ (thisField->ofClass != currentClass)) {
/*0246*/ START_TEMPORARY_ROOTS
/*0247*/ DECLARE_TEMPORARY_ROOT(char *, fieldClassName,
/*0248*/ getClassName((CLASS)(thisField->ofClass)));
/*0249*/ DECLARE_TEMPORARY_ROOT(char *, currentClassName,
/*0250*/ getClassName((CLASS)currentClass));
/*0251*/ sprintf(str_buffer,
/*0252*/ KVM_MSG_CANNOT_MODIFY_FINAL_FIELD_3STRPARAMS,
/*0253*/ fieldClassName, fieldName(thisField),
/*0254*/ currentClassName);
/*0255*/ END_TEMPORARY_ROOTS
/*0256*/ fatalError(str_buffer);
/*0257*/ }
/*0258*/ if (!(thisTag & CP_CACHEBIT)) {
/*0259*/ /* Since access only depends on the class, and not on the
/*0260./ * specific byte code used to access the field, we don't need
/*0261./ * to perform this check if the constant pool entry
/*0262./ * has already been resolved.
/*0263./ */
/*0264*/ if (!classHasAccessToMember(currentClass,
/*0265*/ thisField->accessFlags,
/*0266*/ thisField->ofClass)) {
/*0267*/ START_TEMPORARY_ROOTS
/*0268*/ DECLARE_TEMPORARY_ROOT(char *, fieldClassName,
/*0269*/ getClassName((CLASS)(thisField->ofClass)));
/*0270*/ DECLARE_TEMPORARY_ROOT(char *, currentClassName,
/*0271*/ getClassName((CLASS)currentClass));
/*0272*/ sprintf(str_buffer,
/*0273*/ KVM_MSG_CANNOT_ACCESS_MEMBER_FROM_CLASS_3STRPARAMS,
/*0274*/ fieldClassName, fieldName(thisField),
/*0275*/ currentClassName);
/*0276*/ END_TEMPORARY_ROOTS
/*0277*/ fatalError(str_buffer);
/*0278*/ }
/*0279*/ cachePoolEntry(constantPool, cpIndex, (cell*)thisField);
/*0280*/ }
/*0281*/ }
/*0282*/ return thisField;
/*0283*/}
/*0284*/
/*0285*//*=========================================================================
/*0286./ * FUNCTION: resolveMethodReference()
/*0287./ * TYPE: public instance-level operation
/*0288./ * OVERVIEW: Given an index to a CONSTANT_Methodref or
/*0289./ * CONSTANT_InterfaceMethodref, get the Method
/*0290./ * that the index refers to.
/*0291./ * INTERFACE:
/*0292./ * parameters: constant pool pointer, constant pool index
/*0293./ * returns: method pointer
/*0294./ *=======================================================================*/
/*0295*/
/*0296*/METHOD resolveMethodReference(CONSTANTPOOL constantPool, unsigned int cpIndex,
/*0297*/ bool_t isStatic, INSTANCE_CLASS currentClass) {
/*0298*/ CONSTANTPOOL_ENTRY thisEntry = &constantPool->entries[cpIndex];
/*0299*/ unsigned char thisTag = CONSTANTPOOL_TAG(constantPool, cpIndex);
/*0300*/ if (thisTag & CP_CACHEBIT) {
/*0301*/ /* Check if this entry has already been resolved (cached) */
/*0302*/ /* If so, simply return the earlier resolved class */
/*0303*/ return (METHOD)(thisEntry->cache);
/*0304*/ } else {
/*0305*/ unsigned short classIndex = thisEntry->method.classIndex;
/*0306*/ unsigned short nameTypeIndex = thisEntry->method.nameTypeIndex;
/*0307*/
/*0308*/ CLASS thisClass = resolveClassReference(constantPool,
/*0309*/ classIndex,
/*0310*/ currentClass);
/*0311*/ NameTypeKey nameTypeKey;
/*0312*/ METHOD thisMethod = NULL;
/*0313*/
/*0314*/ if ( (((thisTag & CP_CACHEMASK) == CONSTANT_InterfaceMethodref) &&
/*0315*/ !(thisClass->accessFlags & ACC_INTERFACE))
/*0316*/ ||
/*0317*/ (((thisTag & CP_CACHEMASK) == CONSTANT_Methodref) &&
/*0318*/ (thisClass->accessFlags & ACC_INTERFACE))) {
/*0319*/ /* "Bad methodref" */
/*0320*/ fatalError(KVM_MSG_BAD_FIELD_OR_METHOD_REFERENCE);
/*0321*/ }
/*0322*/
/*0323*/ nameTypeKey = constantPool->entries[nameTypeIndex].nameTypeKey;
/*0324*/ if (IS_ARRAY_CLASS(thisClass) ||
/*0325*/ ((INSTANCE_CLASS)thisClass)->status != CLASS_ERROR) {
/*0326*/ thisMethod = lookupMethod(thisClass, nameTypeKey, currentClass);
//\\
/*0327*/ if (nameTypeKey.nt.nameKey == initNameAndType.nt.nameKey) {
/*0328*/ if (thisMethod != NULL
/*0329*/ && thisMethod->ofClass != (INSTANCE_CLASS)thisClass) {
/*0330*/ thisMethod = NULL;
/*0331*/ }
/*0332*/ }
/*0333*/ }
/*0334*/ if (thisMethod) {
/*0335*/ if (isStatic ? ((thisMethod->accessFlags & ACC_STATIC) == 0)
/*0336*/ : ((thisMethod->accessFlags & ACC_STATIC) != 0)) {
/*0337*/ START_TEMPORARY_ROOTS
/*0338*/ DECLARE_TEMPORARY_ROOT(char*, methodClassName,
/*0339*/ getClassName((CLASS)thisMethod->ofClass));
/*0340*/ DECLARE_TEMPORARY_ROOT(char*, methodSignature,
/*0341*/ getMethodSignature(thisMethod));
/*0342*/ sprintf(str_buffer,
/*0343*/ KVM_MSG_INCOMPATIBLE_CLASS_CHANGE_3STRPARAMS,
/*0344*/ methodClassName,
/*0345*/ methodName(thisMethod), methodSignature);
/*0346*/ fatalVMError(str_buffer);
/*0347*/ END_TEMPORARY_ROOTS
/*0348*/ }
/*0349*/ if (!classHasAccessToMember(currentClass, thisMethod->accessFlags,
/*0350*/ thisMethod->ofClass)) {
/*0351*/ START_TEMPORARY_ROOTS
/*0352*/ DECLARE_TEMPORARY_ROOT(char*, className,
/*0353*/ getClassName((CLASS)currentClass));
/*0354*/ DECLARE_TEMPORARY_ROOT(char*, methodClassName,
/*0355*/ getClassName((CLASS)thisMethod->ofClass));
/*0356*/ sprintf(str_buffer,
/*0357*/ KVM_MSG_CANNOT_ACCESS_MEMBER_FROM_CLASS_3STRPARAMS,
/*0358*/ methodClassName, methodName(thisMethod),
/*0359*/ className);
/*0360*/ END_TEMPORARY_ROOTS
/*0361*/ fatalError(str_buffer);
/*0362*/ }
/*0363*/ cachePoolEntry(constantPool, cpIndex, (cell*)thisMethod);
/*0364*/ } else {
/*0365*/ /* Some appropriate error message in debug mode */
/*0366*/ }
/*0367*/ return thisMethod;
/*0368*/ }
/*0369*/}
/*0370*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -