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

📄 loader.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 2 页
字号:
/*0270*/
/*0271*//*=========================================================================
/*0272./ * FUNCTION:      verifyName()
/*0273./ * TYPE:          private class file load operation
/*0274./ * OVERVIEW:      validate a class, field, or method name
/*0275./ * INTERFACE:
/*0276./ *   parameters:  pointer to a name, name type
/*0277./ *   returns:     nothing
/*0278./ *=======================================================================*/
/*0279*/
/*0280*/bool_t
/*0281*/verifyName(const char* name, enum verifyName_type type, bool_t abortOnError)
/*0282*/{
/*0283*/    bool_t result;
/*0284*/    unsigned short length = (unsigned short)strlen(name);
/*0285*/
/*0286*/    if (length > 0) {
/*0287*/        if (name[0] == '<') {
/*0288*/            result = (type == LegalMethod) && 
/*0289*/                ((strcmp(name, "<init>") == 0) || 
/*0290*/                 (strcmp(name, "<clinit>") == 0));
/*0291*/        } else {
/*0292*/            const char *p;
/*0293*/            if (type == LegalClass && name[0] == '[') {
/*0294*/                p = skipOverFieldType(name, FALSE, length);
/*0295*/            } else {
/*0296*/                p = skipOverFieldName(name, 
/*0297*/                                      type == LegalClass,
/*0298*/                                      length);
/*0299*/            }
/*0300*/            result = (p != NULL) && (p - name == length);
/*0301*/        }
/*0302*/    } else {
/*0303*/        result = FALSE;
/*0304*/    }
/*0305*/    if (!result && abortOnError) { 
/*0306*/        fatalError(KVM_MSG_BAD_NAME);
/*0307*/    } 
/*0308*/    return result;
/*0309*/}
/*0310*/
/*0311*//*=========================================================================
/*0312./ * FUNCTION:      verifyClassFlags()
/*0313./ * TYPE:          private class file load operation
/*0314./ * OVERVIEW:      validate class access flags
/*0315./ * INTERFACE:
/*0316./ *   parameters:  class access flags
/*0317./ *   returns:     nothing
/*0318./ *=======================================================================*/
/*0319*/
/*0320*/static void 
/*0321*/verifyClassFlags(unsigned short flags)
/*0322*/{
/*0323*/    if (flags & ACC_INTERFACE) {
/*0324*/        if ((flags & ACC_ABSTRACT) == 0)
/*0325*/            goto failed;
/*0326*/        if (flags & ACC_FINAL)
/*0327*/            goto failed;
/*0328*/    } else {
/*0329*/        if ((flags & ACC_FINAL) && (flags & ACC_ABSTRACT))
/*0330*/            goto failed;
/*0331*/    }
/*0332*/    return;
/*0333*/    
/*0334*/ failed:
/*0335*/    fatalError(KVM_MSG_BAD_CLASS_ACCESS_FLAGS);
/*0336*/}
/*0337*/
/*0338*//*=========================================================================
/*0339./ * FUNCTION:      verifyFieldFlags()
/*0340./ * TYPE:          private class file load operation
/*0341./ * OVERVIEW:      validate field access flags
/*0342./ * INTERFACE:
/*0343./ *   parameters:  field access flags, isInterface
/*0344./ *   returns:     nothing
/*0345./ *=======================================================================*/
/*0346*/
/*0347*/static void 
/*0348*/verifyFieldFlags(unsigned short flags, unsigned short classFlags)
/*0349*/{
/*0350*/    if ((classFlags & ACC_INTERFACE) == 0) {
/*0351*/        /* Class or instance fields */
/*0352*/        int accessFlags = flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
/*0353*/
/*0354*/        /* Make sure that accessFlags has one of the four legal values, by
/*0355./         * looking it up in a bit mask */
/*0356*/        if (( (1 << accessFlags) & ((1 << 0) + (1 << ACC_PUBLIC) 
/*0357*/             + (1 << ACC_PRIVATE) + (1 << ACC_PROTECTED))) == 0) {
/*0358*/            goto failed;
/*0359*/        }
/*0360*/
/*0361*/        if ((flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE)){
/*0362*/            /* A field can't be both final and volatile */
/*0363*/            goto failed;
/*0364*/        }
/*0365*/    } else { 
/*0366*/        /* interface fields */
/*0367*/        if (flags != (ACC_STATIC | ACC_FINAL | ACC_PUBLIC)) { 
/*0368*/            goto failed;
/*0369*/        }
/*0370*/    }
/*0371*/    return;
/*0372*/    
/*0373*/ failed:
/*0374*/    fatalError(KVM_MSG_BAD_FIELD_ACCESS_FLAGS);
/*0375*/}
/*0376*/
/*0377*//*=========================================================================
/*0378./ * FUNCTION:      verifyFieldType()
/*0379./ * TYPE:          private class file load operation
/*0380./ * OVERVIEW:      validate field signature
/*0381./ * INTERFACE:
/*0382./ *   parameters:  field signature
/*0383./ *   returns:     nothing
/*0384./ *=======================================================================*/
/*0385*/
/*0386*/static void 
/*0387*/verifyFieldType(const char* type)
/*0388*/{
/*0389*/    unsigned short length = (unsigned short)strlen(type);
/*0390*/    const char *p = skipOverFieldType(type, FALSE, length);
/*0391*/
/*0392*/    if (p == NULL || p - type != length) {
/*0393*/        fatalError(KVM_MSG_BAD_FIELD_SIGNATURE);
/*0394*/    }
/*0395*/}
/*0396*/
/*0397*//*=========================================================================
/*0398./ * FUNCTION:      verifyMethodFlags()
/*0399./ * TYPE:          private class file load operation
/*0400./ * OVERVIEW:      validate method access flags
/*0401./ * INTERFACE:
/*0402./ *   parameters:  method access flags, isInterface, methodName
/*0403./ *   returns:     nothing
/*0404./ *=======================================================================*/
/*0405*/
/*0406*/static void 
/*0407*/verifyMethodFlags(unsigned short flags, unsigned short classFlags,
/*0408*/                  const char* name)
/*0409*/{
/*0410*/    /* These are all small bits.  The value is between 0 and 7. */
/*0411*/    int accessFlags = flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
/*0412*/
/*0413*/    /* Make sure that accessFlags has one of the four legal values, by
/*0414./     * looking it up in a bit mask */
/*0415*/
/*0416*/    if (( (1 << accessFlags) 
/*0417*/         & ((1 << 0) 
/*0418*/         | (1 << ACC_PUBLIC) 
/*0419*/         | (1 << ACC_PRIVATE) | (1 << ACC_PROTECTED))) == 0) {
/*0420*/        goto failed;
/*0421*/    }
/*0422*/
/*0423*/    if ((classFlags & ACC_INTERFACE) == 0) {
/*0424*/        /* class or instance methods */
/*0425*/        if (flags & ACC_ABSTRACT) {
/*0426*/            if (flags & (ACC_FINAL | ACC_NATIVE | ACC_SYNCHRONIZED
/*0427*/                | ACC_PRIVATE | ACC_STATIC)) { 
/*0428*/                goto failed;
/*0429*/            }
/*0430*/        }
/*0431*/    } else { 
/*0432*/        /* interface methods */
/*0433*/        if ( (flags & (ACC_ABSTRACT | ACC_PUBLIC | ACC_STATIC)) 
/*0434*/              != (ACC_ABSTRACT | ACC_PUBLIC)) { 
/*0435*/            /* Note that <clinit> is special, and not handled by this
/*0436./             * function.  It's not abstract, and static. */
/*0437*/            goto failed;            
/*0438*/        }
/*0439*/    }
/*0440*/
/*0441*/    if (strcmp(name, "<init>") == 0) {
/*0442*/        if (flags & ~(ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE))
/*0443*/            goto failed;
/*0444*/    } 
/*0445*/    return;
/*0446*/    
/*0447*/ failed:
/*0448*/    fatalError(KVM_MSG_BAD_METHOD_ACCESS_FLAGS);
/*0449*/}
/*0450*/
/*0451*//*=========================================================================
/*0452./ * FUNCTION:      verifyMethodType()
/*0453./ * TYPE:          private class file load operation
/*0454./ * OVERVIEW:      validate method signature
/*0455./ * INTERFACE:
/*0456./ *   parameters:  method name, signature
/*0457./ *   returns:     argument size
/*0458./ *=======================================================================*/
/*0459*/
/*0460*/static unsigned short
/*0461*/verifyMethodType(const char *name, const char* signature)
/*0462*/{
/*0463*/    unsigned short args_size = 0;
/*0464*/    const char *p = signature;
/*0465*/    unsigned short length = (unsigned short)strlen(signature);
/*0466*/    const char *next_p;
/*0467*/
/*0468*/    /* The first character must be a '(' */
/*0469*/    if ((length > 0) && (*p++ == '(')) {
/*0470*/        length--;
/*0471*/        /* Skip over however many legal field signatures there are */
/*0472*/        while ((length > 0) &&
/*0473*/               (next_p = skipOverFieldType(p, FALSE, length))) {
/*0474*/            args_size++;
/*0475*/            if (p[0] == 'J' || p[0] == 'D')
/*0476*/                args_size++;
/*0477*/            length -= (next_p - p);
/*0478*/            p = next_p;
/*0479*/        }
/*0480*/        /* The first non-signature thing better be a ')' */
/*0481*/        if ((length > 0) && (*p++ == ')')) {
/*0482*/            length --;
/*0483*/            if (strlen(name) > 0 && name[0] == '<') {
/*0484*/                /* All internal methods must return void */
/*0485*/                if ((length == 1) && (p[0] == 'V'))
/*0486*/                    return args_size;
/*0487*/            } else {
/*0488*/                /* Now, we better just have a return value. */
/*0489*/                next_p =  skipOverFieldType(p, TRUE, length);
/*0490*/                if (next_p && (length == next_p - p))
/*0491*/                    return args_size;
/*0492*/            }
/*0493*/        }
/*0494*/    }
/*0495*/    fatalError(KVM_MSG_BAD_METHOD_SIGNATURE);
/*0496*/    return 0; /* never reached */
/*0497*/}
/*0498*/
/*0499*//*=========================================================================
/*0500./ * FUNCTION:      verifyConstantPoolEntry()
/*0501./ * TYPE:          private class file load operation
/*0502./ * OVERVIEW:      validate constant pool index
/*0503./ * INTERFACE:
/*0504./ *   parameters:  constant pool, index, and expected tag
/*0505./ *   returns:     nothing
/*0506./ *=======================================================================*/
/*0507*/
/*0508*/static void
/*0509*/verifyConstantPoolEntry(INSTANCE_CLASS CurrentClass,
/*0510*/                        unsigned short index,
/*0511*/                        unsigned char tag)
/*0512*/{
/*0513*/    CONSTANTPOOL ConstantPool = CurrentClass->constPool;
/*0514*/    unsigned short length = (unsigned short)CONSTANTPOOL_LENGTH(ConstantPool);
/*0515*/    unsigned char tag2 = CONSTANTPOOL_TAGS(ConstantPool)[index];
/*0516*/    if (index >= length || tag2 != tag) {
/*0517*/        fatalError(KVM_MSG_BAD_CONSTANT_INDEX);
/*0518*/    }
/*0519*/}
/*0520*/
/*0521*//*=========================================================================
/*0522./ * Class loading operations
/*0523./ *=======================================================================*/
/*0524*/
/*0525*//*=========================================================================
/*0526./ * FUNCTION:      loadVersionInfo()
/*0527./ * TYPE:          private class file load operation
/*0528./ * OVERVIEW:      Load the first few bytes of a Java class file,
/*0529./ *                checking the file type and version information.
/*0530./ * INTERFACE:
/*0531./ *   parameters:  classfile pointer
/*0532./ *   returns:     <nothing>
/*0533./ *=======================================================================*/
/*0534*/
/*0535*/static void 
/*0536*/loadVersionInfo(FILEPOINTER_HANDLE ClassFileH)
/*0537*/{
/*0538*/    UNUSEDPARAMETER(CurrentClass) //\\

⌨️ 快捷键说明

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