⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 5 页
字号:
        unsigned short typeIndex   = loadShort(ClassFileH);        bool_t isStatic = (accessFlags & ACC_STATIC) != 0;        FIELD thisField;        START_TEMPORARY_ROOTS            DECLARE_TEMPORARY_ROOT(const char *, fieldName,                                    getUTF8String(StringPoolH, nameIndex));            DECLARE_TEMPORARY_ROOT(const char *, signature,                                    getUTF8String(StringPoolH, typeIndex));            NameTypeKey result;            verifyFieldFlags(accessFlags, CurrentClass->clazz.accessFlags);            verifyName(fieldName, LegalField, TRUE);            verifyFieldType(signature);            result.nt.nameKey =                 change_Name_to_Key(&fieldName, 0, strlen(fieldName));            result.nt.typeKey =                 change_FieldSignature_to_Key(&signature, 0, strlen(signature));                ASSERTING_NO_ALLOCATION                thisField = &CurrentClass->fieldTable->fields[index];#if INCLUDEDEBUGCODE            if (traceclassloadingverbose) {                 fprintf(stdout, "Field '%s' loaded\n", fieldName);            }#endif /* INCLUDEDEBUGCODE */                /* Check if the field is double length, or is a pointer type.                 * If so set the appropriate bit in the word */                switch (signature[0]) {                    case 'D': case 'J':   accessFlags |= ACC_DOUBLE;   break;                     case 'L': case '[':   accessFlags |= ACC_POINTER;  break;                }                /*  Store the corresponding information in the structure */                thisField->nameTypeKey = result;                thisField->ofClass     = CurrentClass;                thisField->accessFlags = accessFlags;                if (isStatic) {                     loadStaticFieldAttributes(ClassFileH, CurrentClass,                                              thisField, StringPoolH);                    if (accessFlags & ACC_POINTER) {                         staticPtrCount++;                    } else {                        staticNonPtrCount += (accessFlags & ACC_DOUBLE) ? 2 : 1;                    }                 } else {                     ignoreAttributes(ClassFileH, StringPoolH);                }            END_ASSERTING_NO_ALLOCATION        END_TEMPORARY_ROOTS    }    /* We know go back and look at each of the static fields again. */    if (staticPtrCount > 0 || staticNonPtrCount > 0) {         /* We put all the statics into a POINTERLIST.  We specifically make         * a POINTERLIST in which the real length is longer than the value         * put into the length field.  The garbage collector only will look         * at the first "length" fields.         * So all the pointer statics go before all the non-pointer statics.         *         * As a hack, loadStaticFieldAttributes() has put into the offset         * field the constant pool entry containing the static's initial         * value.  The static field should be initialized appropriately         * once space for it has been allocated          */        /* Allocate space for all the pointers and non pointers.           */        int staticsSize = SIZEOF_POINTERLIST(staticNonPtrCount+staticPtrCount);        POINTERLIST statics = (POINTERLIST)callocPermanentObject(staticsSize);        /* All the non-pointers go after all the pointers */        void **nextPtrField = (void **)statics->data;        void **nextNonPtrField = nextPtrField + staticPtrCount;        /* Set the length field so that the GC only looks at the pointers */        statics->length = staticPtrCount;        CurrentClass->staticFields = statics;        ASSERTING_NO_ALLOCATION            CONSTANTPOOL ConstantPool = CurrentClass->constPool;            if (USESTATIC) {                 /* Otherwise, this is in permanent memory and won't move */                fieldTable = CurrentClass->fieldTable;            }             FOR_EACH_FIELD(thisField, fieldTable)                 long accessFlags = thisField->accessFlags;                unsigned short cpIndex;                if (!(accessFlags & ACC_STATIC)) {                     continue;                }                cpIndex = (unsigned short)(thisField->u.offset);                if (thisField->accessFlags & ACC_POINTER) {                     /* The only possible initialization is for a string */                    thisField->u.staticAddress = nextPtrField;                    if (cpIndex != 0) {                         verifyConstantPoolEntry(CurrentClass, cpIndex,                                                CONSTANT_String);                        *(INTERNED_STRING_INSTANCE *)nextPtrField =                             CP_ENTRY(cpIndex).String;                    }                    nextPtrField++;                } else {                    thisField->u.staticAddress = nextNonPtrField;                    if (cpIndex != 0) {                         unsigned char tag;                        switch(thisField->nameTypeKey.nt.typeKey) {                             case 'B': case 'C': case 'Z': case 'S': case 'I':                                tag = CONSTANT_Integer;                                break;                            case 'F':#if !IMPLEMENTS_FLOAT                                fatalError(KVM_MSG_FLOATING_POINT_NOT_SUPPORTED);#endif                                tag = CONSTANT_Float;                                break;                            case 'D':#if !IMPLEMENTS_FLOAT                                fatalError(KVM_MSG_FLOATING_POINT_NOT_SUPPORTED);#endif                                tag = CONSTANT_Double;                                break;                            case 'J':                                tag = CONSTANT_Long;                                break;                            default:                                fatalError(KVM_MSG_BAD_SIGNATURE);                        }                        verifyConstantPoolEntry(CurrentClass, cpIndex, tag);                        if (accessFlags & ACC_DOUBLE) {                                             /* Initialize a double or long */                            CONSTANTPOOL_ENTRY thisEntry = &CP_ENTRY(cpIndex);                            unsigned long hiBytes, loBytes;                            hiBytes = (unsigned long)(thisEntry[0].integer);                            loBytes = (unsigned long)(thisEntry[1].integer);                            SET_LONG_FROM_HALVES(nextNonPtrField,                                                  hiBytes, loBytes);                        } else {                             *(cell *)nextNonPtrField =                                CP_ENTRY(cpIndex).integer;                        }                                           }                    nextNonPtrField += (accessFlags & ACC_DOUBLE) ? 2 : 1;                }            END_FOR_EACH_FIELD        END_ASSERTING_NO_ALLOCATION    }    if (fieldCount >= 2) {         if (USESTATIC) {             /* Otherwise, this is in permanent memory and won't move */            fieldTable = CurrentClass->fieldTable;        }        ASSERTING_NO_ALLOCATION            /* Check to see if there are two fields with the same name/type */            FIELD firstField = &fieldTable->fields[0];            FIELD lastField = firstField + (fieldCount - 1);            FIELD outer, inner;            for (outer = firstField; outer < lastField; outer++) {                 for (inner = outer + 1; inner <= lastField; inner++) {                     if (outer->nameTypeKey.i == inner->nameTypeKey.i) {                         fatalError(KVM_MSG_DUPLICATE_FIELD_FOUND);                    }                }            }        END_ASSERTING_NO_ALLOCATION    }#if INCLUDEDEBUGCODE    if (traceclassloadingverbose)        fprintf(stdout, "Fields loaded ok\n");#endif /* INCLUDEDEBUGCODE */}/*========================================================================= * FUNCTION:      loadExceptionHandlers() * TYPE:          private class file load operation * OVERVIEW:      Load the exception handling information associated *                with each method in a class file.  * INTERFACE: *   parameters:  constant pool, classfile pointer, method pointer *   returns:     number of characters read from the class file *=======================================================================*/static int loadExceptionHandlers(FILEPOINTER_HANDLE ClassFileH, METHOD_HANDLE thisMethodH){    unsigned short numberOfHandlers = loadShort(ClassFileH);    if (numberOfHandlers > 0) {        HANDLERTABLE handlerTable;        METHOD thisMethod;        int tableSize = SIZEOF_HANDLERTABLE(numberOfHandlers);#if USESTATIC        handlerTable = (HANDLERTABLE)callocObject(tableSize, GCT_NOPOINTERS);#else        handlerTable = (HANDLERTABLE)callocPermanentObject(tableSize);#endif        handlerTable->length = numberOfHandlers;        thisMethod = unhand(thisMethodH);        thisMethod->u.java.handlers = handlerTable;        ASSERTING_NO_ALLOCATION            FOR_EACH_HANDLER(thisHandler, handlerTable)                 unsigned short startPC   = loadShort(ClassFileH);                unsigned short endPC     = loadShort(ClassFileH);                unsigned short handlerPC = loadShort(ClassFileH);                unsigned short exception = loadShort(ClassFileH);                if (startPC >= thisMethod->u.java.codeLength ||                    endPC > thisMethod->u.java.codeLength ||                     startPC >= endPC ||                    handlerPC >= thisMethod->u.java.codeLength) {                    fatalError(KVM_MSG_BAD_EXCEPTION_HANDLER_FOUND);                }                if (exception != 0) {                    verifyConstantPoolEntry(thisMethod->ofClass,                                            exception, CONSTANT_Class);                }                thisHandler->startPC   = startPC;                thisHandler->endPC     = endPC;                thisHandler->handlerPC = handlerPC;                thisHandler->exception = exception;            END_FOR_EACH_HANDLER        END_ASSERTING_NO_ALLOCATION    } else {        /*  Method has no associated exception handlers */        unhand(thisMethodH)->u.java.handlers = NULL;    }    return (numberOfHandlers * 8 + 2);}/*========================================================================= * FUNCTION:      loadStackMaps() * TYPE:          private class file load operation * OVERVIEW:      Load the stack maps associated *                with each method in a class file.  * INTERFACE: *   parameters:  classfile pointer, method pointer, constant pool *   returns:     number of characters read from the class file *=======================================================================*/static longloadStackMaps(FILEPOINTER_HANDLE ClassFileH, METHOD_HANDLE thisMethodH){    long bytesRead;    INSTANCE_CLASS CurrentClass = unhand(thisMethodH)->ofClass;    START_TEMPORARY_ROOTS        unsigned short nStackMaps = loadShort(ClassFileH);        DECLARE_TEMPORARY_ROOT(POINTERLIST, stackMaps,             (POINTERLIST)callocObject(SIZEOF_POINTERLIST(2*nStackMaps),                                       GCT_POINTERLIST));        METHOD thisMethod = unhand(thisMethodH); /* Very volatile */        unsigned tempSize = (thisMethod->u.java.maxStack + thisMethod->frameSize + 2);        DECLARE_TEMPORARY_ROOT(unsigned short*, stackMap,            (unsigned short *)mallocBytes(sizeof(unsigned short) * tempSize));        unsigned short stackMapIndex;        stackMaps->length = nStackMaps;        unhand(thisMethodH)->u.java.stackMaps.verifierMap = stackMaps;        bytesRead = 2;        for (stackMapIndex = 0; stackMapIndex < nStackMaps; stackMapIndex++) {            unsigned short i, index;            /* Any allocation happens at the end, so we have to dereference this             * at least once through each loop.              */            thisMethod = unhand(thisMethodH);            /* Read in the offset */            stackMaps->data[stackMapIndex + nStackMaps].cell =                 loadShort(ClassFileH);            bytesRead += 2;            for (index = 0, i = 0 ; i < 2; i++) {                unsigned short j;                unsigned short size = loadShort(ClassFileH);                unsigned short size_delta = 0;                unsigned short size_index = index++;                unsigned short maxSize = (i == 0 ? thisMethod->frameSize                                                  : thisMethod->u.java.maxStack);                bytesRead += 2;                for (j = 0; j < size; j++) {                    unsigned char stackType = loadByte(ClassFileH);                    bytesRead += 1;                    /* We are reading the j-th element of the stack map.                     * This corresponds to the value in the j + size_delta'th                     * local register or stack location                      */                    if (j + size_delta >= maxSize) {                         fatalError(KVM_MSG_BAD_STACKMAP);                    } else if (stackType == ITEM_NewObject) {                        unsigned short instr = loadShort(ClassFileH);                        bytesRead += 2;                        if (instr >= thisMethod->u.java.codeLength) {                            fatalError(KVM_MSG_BAD_NEWOBJECT);                        }                        stackMap[index++] = ENCODE_NEWOBJECT(instr);                    } else if (stackType < ITEM_Object) {                        stackMap[index++] = stackType;                        if (stackType == ITEM_Long || stackType == ITEM_Double){                            if (j + size_delta + 1 >= maxSize) {                                 fatalError(KVM_MSG_BAD_STACKMAP);                            }                            stackMap[index++] = (stackType == ITEM_Long)                                                     ? ITEM_Long_2                                                     : ITEM_Double_2;                            size_delta++;                        }                    } else if (stackType == ITEM_Object) {                        unsigned short classIndex = loadShort(ClassFileH);                        CONSTANTPOOL ConstantPool = CurrentClass->constPool;                        CLASS clazz;                        bytesRead += 2;                        verifyConstantPoolEntry(CurrentClass,                                                 classIndex, CONSTANT_Class);                        clazz = CP_ENTRY(classIndex).clazz;                        stackMap[index++] = clazz->key;                    } else {                        fatalError(KVM_MSG_BAD_STACKMAP);                    }                }                stackMap[size_index] = size + size_delta;            }                /* We suspect that there will be a lot of duplication, so it's worth             * it to check and see if we already have this identical string */            for (i = 0; ; i++) {                if (i == stackMapIndex) {                     /* We've reached the end, and no duplicate found */                    char *temp = mallocBytes(index * sizeof(unsigned short));                    memcpy(temp, stackMap, index * sizeof(short));                    stackMaps->data[stackMapIndex].cellp = (cell*)temp;                    break;                } else if (memcmp(stackMap, stackMaps->data[i].cellp,                                   index * sizeof(short)) == 0) {                     /* We have found a duplicate */                    stackMaps->data[stackMapIndex] = stackMaps->data[i];                    break;                } 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -