📄 loader.c
字号:
(CONSTANTPOOL)callocObject(tableSize, GCT_NOPOINTERS));#else ConstantPool = (CONSTANTPOOL)callocPermanentObject(tableSize);#endif CONSTANTPOOL_LENGTH(ConstantPool) = numberOfEntries; CurrentClass->constPool = ConstantPool; } /* Now create the constant pool entries */ for (cpIndex = 1; cpIndex < constantCount; cpIndex++) { /* These can move between iterations of the loop */ unsigned char *Tags = (unsigned char *)(&RawPool[constantCount]); unsigned char *CPTags = CONSTANTPOOL_TAGS(ConstantPool); unsigned char tag = Tags[cpIndex]; if (cpIndex <= lastNonUtfIndex) { CPTags[cpIndex] = tag; } switch (tag) { case CONSTANT_Class: { unsigned short nameIndex = (unsigned short)RAW_POOL(cpIndex).integer; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(const char *, name, getUTF8String(&StringPool, nameIndex)); verifyName(name, LegalClass, TRUE); CP_ENTRY(cpIndex).clazz = getRawClassX(&name, 0, strlen(name)); END_TEMPORARY_ROOTS break; } case CONSTANT_String: { unsigned short nameIndex = (unsigned short)RAW_POOL(cpIndex).integer; char *name = getUTF8String(&StringPool, nameIndex); INTERNED_STRING_INSTANCE string = internString(name, strlen(name)); CP_ENTRY(cpIndex).String = string; break; } case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { /* Two 16-bit entries */ unsigned short classIndex = RAW_POOL(cpIndex).method.classIndex; unsigned short nameTypeIndex =RAW_POOL(cpIndex).method.nameTypeIndex; if (classIndex >= constantCount || Tags[classIndex] != CONSTANT_Class || nameTypeIndex >= constantCount || Tags[nameTypeIndex] != CONSTANT_NameAndType) { fatalError(KVM_MSG_BAD_FIELD_OR_METHOD_REFERENCE); } else { unsigned short typeIndex = RAW_POOL(nameTypeIndex).nameTypeKey.nt.typeKey; char* type = getUTF8String(&StringPool, typeIndex); if (tag == CONSTANT_Fieldref && type[0] == '(') { fatalError(KVM_MSG_BAD_NAME_OR_TYPE_REFERENCE); } CP_ENTRY(cpIndex) = RAW_POOL(cpIndex); } break; } case CONSTANT_Double:#if !IMPLEMENTS_FLOAT fatalError(KVM_MSG_FLOATING_POINT_NOT_SUPPORTED);#endif case CONSTANT_Long: CP_ENTRY(cpIndex).integer = RAW_POOL(cpIndex).integer; cpIndex++; CPTags[cpIndex] = 0; CP_ENTRY(cpIndex).integer = RAW_POOL(cpIndex).integer; break; case CONSTANT_Float: #if !IMPLEMENTS_FLOAT fatalError(KVM_MSG_FLOATING_POINT_NOT_SUPPORTED);#endif case CONSTANT_Integer: CP_ENTRY(cpIndex).integer = RAW_POOL(cpIndex).integer; break; case CONSTANT_NameAndType: { unsigned short nameIndex = RAW_POOL(cpIndex).nameTypeKey.nt.nameKey; unsigned short typeIndex = RAW_POOL(cpIndex).nameTypeKey.nt.typeKey; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(const char *, name, getUTF8String(&StringPool, nameIndex)); DECLARE_TEMPORARY_ROOT(const char *, type, getUTF8String(&StringPool, typeIndex)); NameKey nameKey; unsigned short typeKey; if (type[0] == '(') { verifyName(name, LegalMethod, TRUE); verifyMethodType(name, type); typeKey = change_MethodSignature_to_Key(&type, 0, strlen(type)); } else { verifyName(name, LegalField, TRUE); verifyFieldType(type); typeKey = change_FieldSignature_to_Key(&type, 0, strlen(type)); } nameKey = change_Name_to_Key(&name, 0, strlen(name)); CP_ENTRY(cpIndex).nameTypeKey.nt.nameKey = nameKey; CP_ENTRY(cpIndex).nameTypeKey.nt.typeKey = typeKey; END_TEMPORARY_ROOTS break; } case CONSTANT_Utf8: /* We don't need these after loading time. So why bother */ if (cpIndex <= lastNonUtfIndex) { CP_ENTRY(cpIndex).integer = 0; CPTags[cpIndex] = 0; } break; default: fatalVMError(KVM_MSG_INVALID_CONSTANT_POOL_ENTRY); break; } } result = StringPool; END_TEMPORARY_ROOTS return result;} /*========================================================================= * FUNCTION: loadClassInfo() * TYPE: private class file load operation * OVERVIEW: Load the access flag, thisClass and superClass * parts of a Java class file. * INTERFACE: * parameters: classfile pointer, current constant pool pointer * returns: Pointer to class runtime structure *=======================================================================*/static voidloadClassInfo(FILEPOINTER_HANDLE ClassFileH, INSTANCE_CLASS CurrentClass){ INSTANCE_CLASS thisClass; INSTANCE_CLASS superClass; CONSTANTPOOL ConstantPool = CurrentClass->constPool; unsigned short accessFlags = loadShort(ClassFileH) & RECOGNIZED_CLASS_FLAGS; verifyClassFlags(accessFlags); { unsigned short thisClassIndex = loadShort(ClassFileH); verifyConstantPoolEntry(CurrentClass, thisClassIndex, CONSTANT_Class); thisClass = (INSTANCE_CLASS)CP_ENTRY(thisClassIndex).clazz; if (CurrentClass != thisClass) { NoClassDefFoundError(CurrentClass); } } { unsigned short superClassIndex = loadShort(ClassFileH); if (superClassIndex == 0) { superClass = NULL; } else { verifyConstantPoolEntry(CurrentClass, superClassIndex, CONSTANT_Class); superClass = (INSTANCE_CLASS)CP_ENTRY(superClassIndex).clazz; } }#if INCLUDEDEBUGCODE if (traceclassloadingverbose) { fprintf(stdout, "Loading class info\n"); }#endif /* INCLUDEDEBUGCODE */ if ((superClass == NULL && (ROMIZING || CurrentClass != JavaLangObject)) || (superClass != JavaLangObject && (accessFlags & ACC_INTERFACE)) ) { fatalError(KVM_MSG_BAD_SUPERCLASS); } CurrentClass->superClass = superClass; CurrentClass->clazz.accessFlags = accessFlags;#if INCLUDEDEBUGCODE if (traceclassloadingverbose) fprintf(stdout, "Class info loaded ok\n");#endif /* INCLUDEDEBUGCODE */}/*========================================================================= * FUNCTION: loadInterfaces() * TYPE: private class file load operation * OVERVIEW: Load the interface part of a Java class file. * INTERFACE: * parameters: classfile pointer, current class pointer * returns: <nothing> *=======================================================================*/static void loadInterfaces(FILEPOINTER_HANDLE ClassFileH, INSTANCE_CLASS CurrentClass){ unsigned short interfaceCount = loadShort(ClassFileH); long byteSize = (interfaceCount+1) * sizeof(unsigned short); unsigned int ifIndex;#if INCLUDEDEBUGCODE if (traceclassloadingverbose) { fprintf(stdout, "Loading interfaces\n"); }#endif /* INCLUDEDEBUGCODE */ if (interfaceCount == 0) { return; } if (USESTATIC) { CurrentClass->ifaceTable = (unsigned short *)mallocBytes(byteSize); } else { long cellSize = ByteSizeToCellSize(byteSize); CurrentClass->ifaceTable = (unsigned short*)callocPermanentObject(cellSize); } /* Store length in the first slot */ CurrentClass->ifaceTable[0] = interfaceCount; for (ifIndex = 1; ifIndex <= interfaceCount; ifIndex++) { unsigned short cpIndex = loadShort(ClassFileH); verifyConstantPoolEntry(CurrentClass, cpIndex, CONSTANT_Class); CurrentClass->ifaceTable[ifIndex] = cpIndex; }#if INCLUDEDEBUGCODE if (traceclassloadingverbose) { fprintf(stdout, "Interfaces loaded ok\n"); }#endif /* INCLUDEDEBUGCODE */}/*========================================================================= * FUNCTION: loadStaticFieldAttributes() * TYPE: private class file load operation * OVERVIEW: Load the "ConstantValue" attribute of a static field, * ignoring all the other possible field attributes. * INTERFACE: * parameters: classfile pointer, constant pool pointer, * field attribute count, pointer to the runtime field struct * returns: <nothing> * * COMMENTS: this function sets the u.offset field of the field to the * constant pool entry that should contain its initial value, or * to 0 if there is no initial value. *=======================================================================*/static void loadStaticFieldAttributes(FILEPOINTER_HANDLE ClassFileH, INSTANCE_CLASS CurrentClass, FIELD thisField, POINTERLIST_HANDLE StringPoolH){ int cpIndex = 0; unsigned short attrCount = loadShort(ClassFileH); unsigned short attrIndex; /* See if the field has any attributes in the class file */ for (attrIndex = 0; attrIndex < attrCount; attrIndex++) { unsigned short attrNameIndex = loadShort(ClassFileH); unsigned long attrLength = loadCell(ClassFileH); const char* attrName = getUTF8String(StringPoolH, attrNameIndex); /* Check if the attribute represents a constant value index */ if (!strcmp(attrName, "ConstantValue")) { if (attrLength != 2) { fatalError(KVM_MSG_BAD_CONSTANTVALUE_LENGTH); } if (cpIndex != 0) { fatalError(KVM_MSG_DUPLICATE_CONSTANTVALUE_ATTRIBUTE); } /* Read index to a constant in constant pool */ cpIndex = loadShort(ClassFileH); if (cpIndex == 0) { fatalError(KVM_MSG_BAD_CONSTANT_INDEX); } } else { /* Unrecognized attribute; read the bytes to /dev/null */ skipBytes(ClassFileH, attrLength); } } thisField->u.offset = cpIndex;}/*========================================================================= * FUNCTION: loadFields() * TYPE: private class file load operation * OVERVIEW: Load the fields (static & instance variables) defined * in a Java class file. * INTERFACE: * parameters: classfile pointer, current class pointer * returns: <nothing> *=======================================================================*/static void loadFields(FILEPOINTER_HANDLE ClassFileH, INSTANCE_CLASS CurrentClass, POINTERLIST_HANDLE StringPoolH){ unsigned short fieldCount = loadShort(ClassFileH); int fieldTableSize = SIZEOF_FIELDTABLE(fieldCount); FIELDTABLE fieldTable; unsigned int index; int staticPtrCount = 0; int staticNonPtrCount = 0; #if INCLUDEDEBUGCODE if (traceclassloadingverbose) { fprintf(stdout, "Loading fields\n"); } #endif /* INCLUDEDEBUGCODE */ if (fieldCount == 0) { return; } /* Create a new field table */#if USESTATIC fieldTable = (FIELDTABLE)callocObject(fieldTableSize, GCT_NOPOINTERS);#else fieldTable = (FIELDTABLE)callocPermanentObject(fieldTableSize);#endif /* Store the size of the table at the beginning of the table */ fieldTable->length = fieldCount; CurrentClass->fieldTable = fieldTable; for (index = 0; index < fieldCount; index++) { unsigned short accessFlags = loadShort(ClassFileH) & RECOGNIZED_FIELD_FLAGS; unsigned short nameIndex = loadShort(ClassFileH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -