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

📄 verifier.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 5 页
字号:
/*0643./ *   returns:     number of words occupied by the resulting type.
/*0644./ *=======================================================================*/
/*0645*/
/*0646*/static int
/*0647*/change_Field_to_StackType(unsigned short fieldType, unsigned short* stackTypeP)
/*0648*/{
/*0649*/    switch (fieldType) {
/*0650*/        case 'I':
/*0651*/        case 'B':
/*0652*/        case 'Z':
/*0653*/        case 'C':
/*0654*/        case 'S':
/*0655*/            *stackTypeP++ = ITEM_Integer;
/*0656*/            return 1;
/*0657*/#if IMPLEMENTS_FLOAT
/*0658*/        case 'F':
/*0659*/            *stackTypeP++ = ITEM_Float;
/*0660*/            return 1;
/*0661*/        case 'D':
/*0662*/            *stackTypeP++ = ITEM_Double;
/*0663*/            *stackTypeP++ = ITEM_Double_2;
/*0664*/            return 2;
/*0665*/#endif
/*0666*/        case 'J':
/*0667*/            *stackTypeP++ = ITEM_Long;
/*0668*/            *stackTypeP++ = ITEM_Long_2;
/*0669*/            return 2;
/*0670*/        default:
/*0671*/            *stackTypeP++ = fieldType;
/*0672*/            return 1;
/*0673*/    }
/*0674*/}
/*0675*/
/*0676*//*=========================================================================
/*0677./ * FUNCTION:      change_Arg_to_StackType
/*0678./ * TYPE:          private operation on type keys
/*0679./ * OVERVIEW:      Change an individual method argument type to a stack type
/*0680./ *
/*0681./ * INTERFACE:
/*0682./ *   parameters:  sigP: pointer to method signature.
/*0683./ *                type: pointer for placing the corresponding stack type(s)
/*0684./ *   returns:     number of words occupied by the resulting type.
/*0685./ *=======================================================================*/
/*0686*/
/*0687*/static int
/*0688*/change_Arg_to_StackType(unsigned char** sigP, unsigned short* typeP)
/*0689*/{
/*0690*/    unsigned char *sig = *sigP;
/*0691*/    unsigned short hi, lo;
/*0692*/
/*0693*/    hi = *sig++;
/*0694*/
/*0695*/    if (hi == 'L') {
/*0696*/        hi = *sig++;
/*0697*/        lo = *sig++;
/*0698*/        *sigP = sig;
/*0699*/        return change_Field_to_StackType((unsigned short)((hi << 8) + lo), typeP);
/*0700*/    }
/*0701*/    if (hi < 'A' || hi > 'Z') {
/*0702*/        lo = *sig++;
/*0703*/        *sigP = sig;
/*0704*/        return change_Field_to_StackType((unsigned short)((hi << 8) + lo), typeP);
/*0705*/    }
/*0706*/    *sigP = sig;
/*0707*/    return change_Field_to_StackType(hi, typeP);
/*0708*/}
/*0709*/
/*0710*//*=========================================================================
/*0711./ * FUNCTION:      getStackType
/*0712./ * TYPE:          private operation on type keys
/*0713./ * OVERVIEW:      Get the recorded stack map of a given target ip.
/*0714./ *
/*0715./ * INTERFACE:
/*0716./ *   parameters:  thisMethod: method being verified.
/*0717./ *                this_ip: current ip (unused for now).
/*0718./ *                target_ip: target ip (to look for a recored stack map).
/*0719./ *   returns:     a stack map
/*0720./ *=======================================================================*/
/*0721*/
/*0722*/static unsigned short *
/*0723*/getStackMap(METHOD thisMethod, unsigned short this_ip, unsigned short target_ip)
/*0724*/{
/*0725*/    POINTERLIST stackMaps = thisMethod->u.java.stackMaps.verifierMap;
/*0726*/    unsigned short i;
/*0727*/    if (stackMaps == NULL) {
/*0728*/        return NULL;
/*0729*/    } else { 
/*0730*/        long length = stackMaps->length; /* number of entries */
/*0731*/        for (i = 0; i < length; i++) {
/*0732*/            if (target_ip == stackMaps->data[i + length].cell) {
/*0733*/                return (unsigned short*)stackMaps->data[i].cellp;
/*0734*/            }
/*0735*/        }
/*0736*/    }
/*0737*/    return NULL;
/*0738*/}
/*0739*/
/*0740*//*=========================================================================
/*0741./ * FUNCTION:      matchStackMap
/*0742./ * TYPE:          private operation on type keys
/*0743./ * OVERVIEW:      Match two stack maps.
/*0744./ *
/*0745./ * INTERFACE:
/*0746./ *   parameters:  thisMethod: method being verified.
/*0747./ *                this_ip: current ip (unused for now).
/*0748./ *                target_ip: target ip (to look for a recored stack map).
/*0749./ *                flags: bit-wise or of the SM_* flags.
/*0750./ *   returns:     TRUE if match, FALSE otherwise.
/*0751./ *=======================================================================*/
/*0752*/
/*0753*/static bool_t 
/*0754*/matchStackMap(METHOD thisMethod, unsigned short this_ip,
/*0755*/              unsigned short target_ip, int flags)
/*0756*/{
/*0757*/    bool_t result = TRUE;  /* Assume result is TRUE */
/*0758*/    unsigned short nstack;
/*0759*/    unsigned short nlocals;
/*0760*/    unsigned short i;
/*0761*/
/*0762*/    /* Following is volatile, and will disappear at first GC */
/*0763*/    unsigned short *stackMapBase = getStackMap(thisMethod, this_ip, target_ip);
/*0764*/
/*0775*/    if (stackMapBase == NULL) {
/*0781*/        return !(flags & SM_EXIST);
/*0782*/    } 
/*0783*/
/*0784*/  START_TEMPORARY_ROOTS
/*0785*/    DECLARE_TEMPORARY_ROOT_FROM_BASE(unsigned short*, stackMap, 
/*0786*/                                     stackMapBase, stackMapBase);
/*0787*/
/*0794*/    nlocals = *stackMap++;
/*0795*/    for (i = 0; i < nlocals; i++) {
/*0796*/        unsigned short ty = *stackMap++;
/*0797*/        unsigned short mergedType = ty;
/*0798*/        if ((SM_CHECK & flags) && !vIsAssignable(vLocals[i], ty, &mergedType)) {
/*0799*/            result = FALSE;
/*0800*/            goto done;
/*0801*/        }
/*0802*/        if (SM_MERGE & flags) {
/*0803*/            vLocals[i] = mergedType;
/*0804*/        }
/*0805*/    }
/*0806*/    if (SM_MERGE & flags) {
/*0807*/        for (i = nlocals; i < vFrameSize; i++) {
/*0808*/            vLocals[i] = ITEM_Bogus;
/*0809*/        }
/*0810*/    }
/*0811*/
/*0812*/    nstack = *stackMap++;
/*0813*/    if ((SM_CHECK & flags) && nstack != vSP) {
/*0814*/        result = FALSE;
/*0815*/        goto done;
/*0816*/    }
/*0817*/    if (SM_MERGE & flags) {
/*0818*/        vSP = nstack;
/*0819*/    }
/*0820*/    for (i = 0; i < nstack; i++) {
/*0821*/        unsigned short ty = *stackMap++;
/*0822*/        unsigned short mergedType = ty;
/*0823*/        if ((SM_CHECK & flags) && !vIsAssignable(vStack[i], ty, &mergedType)) {
/*0824*/            result = FALSE;
/*0825*/            goto done;
/*0826*/        }
/*0827*/        if (SM_MERGE & flags) {
/*0828*/            vStack[i] = mergedType;
/*0829*/        }
/*0830*/    }
/*0831*/ done:
/*0832*/  END_TEMPORARY_ROOTS   
/*0833*/  return result;
/*0834*/}
/*0835*/
/*0836*//*=========================================================================
/*0837./ * FUNCTION:      checkNewObject
/*0838./ * TYPE:          private operation on type keys
/*0839./ * OVERVIEW:      Check if uninitialized objects exist on backward branches.
/*0840./ *
/*0841./ * INTERFACE:
/*0842./ *   parameters:  this_ip: current ip
/*0843./ *                target_ip: branch target ip
/*0844./ *   returns:     TRUE if no uninitialized objects exist, FALSE otherwise.
/*0845./ *=======================================================================*/
/*0846*/
/*0847*/static bool_t 
/*0848*/checkNewObject(unsigned short this_ip, unsigned short target_ip)
/*0849*/{
/*0850*/    if (target_ip < this_ip) {
/*0851*/        int i;
/*0852*/        for (i = 0; i < vFrameSize; i++) {
/*0853*/            if (vLocals[i] & ITEM_NewObject_Flag) {
/*0854*/                return FALSE;
/*0855*/            }
/*0856*/        }
/*0857*/        for (i = 0; i < vSP; i++) {
/*0858*/            if (vStack[i] & ITEM_NewObject_Flag) {
/*0859*/                return FALSE;
/*0860*/            }
/*0861*/        }
/*0862*/    }
/*0863*/    return TRUE;
/*0864*/}
/*0865*/
/*0866*//*=========================================================================
/*0867./ * FUNCTION:      verifyMethod
/*0868./ * TYPE:          private operation on methods.
/*0869./ * OVERVIEW:      Perform byte-code verification of a given method.
/*0870./ *
/*0871./ * INTERFACE:
/*0872./ *   parameters:  thisMethod: method to be verified.
/*0873./ *   returns:     0 if verification succeeds, error code if verification
/*0874./ *                fails.
/*0875./ *=======================================================================*/
/*0876*/
/*0877*/static int 
/*0878*/verifyMethod(METHOD thisMethod)
/*0879*/{
/*0880*/    int result = 0;
/*0881*/    unsigned short ip = 0;     /* virtual ip */
/*0882*/
/*0883*/    START_TEMPORARY_ROOTS
/*0884*/    unsigned short stackMapIndex = 0; 
/*0885*/                               /* index into the StackMap table (corresponds
/*0886./                                * to jump targets).
/*0887./                                */
/*0888*/
/*0889*/    unsigned char *code = thisMethod->u.java.code;
/*0890*/    unsigned short codeLength = thisMethod->u.java.codeLength;
/*0891*/    CONSTANTPOOL constPool = thisMethod->ofClass->constPool;
/*0892*/
/*0893*/    unsigned char* returnSig;  /* holds the return signature */
/*0894*/    unsigned short index;
/*0895*/    unsigned short typeKey;
/*0896*/    unsigned char tag;
/*0897*/    bool_t noControlFlow;      /* set to TRUE where is no direct control
/*0898./                                * flow from current instruction to the next
/*0899./                                * instruction in sequence.
/*0900./                                */
/*0901*/    
/*0902*/    /* This bitmap keeps track of all the NEW instructions that we have
/*0903./     * already seen. 
/*0904./     */
/*0905*/    DECLARE_TEMPORARY_ROOT(unsigned long *, NEWInstructions, NULL);
/*0906*/
/*0907*/    /* Fix bug 4336036.  Need to check for "final" methods when non-static */
/*0908*/    if ((thisMethod->accessFlags & ACC_STATIC) == 0) {
/*0909*/        if (ROMIZING || thisMethod->ofClass != JavaLangObject) { 
/*0910*/            INSTANCE_CLASS thisClass = thisMethod->ofClass;
/*0911*/            INSTANCE_CLASS superClass = thisClass->superClass;
/*0912*/            METHOD superMethod = 
/*0913*/                lookupMethod((CLASS)superClass, thisMethod->nameTypeKey, 
/*0914*/                             thisClass);
/*0915*/            if (superMethod != NULL && (superMethod->accessFlags & ACC_FINAL)) {
/*0916*/                VERIFIER_ERROR(VE_FINAL_METHOD_OVERRIDE);
/*0917*/            }
/*0918*/        }
/*0919*/    }
/*0920*/
/*0921*/    vMaxStack = thisMethod->u.java.maxStack;
/*0922*/    vFrameSize = thisMethod->frameSize;
/*0923*/    IS_TEMPORARY_ROOT(vStack,
/*0924*/        (unsigned short*)
/*0925*/        callocObject(vMaxStack * sizeof(unsigned short), GCT_NOPOINTERS));
/*0926*/    IS_TEMPORARY_ROOT(vLocals, 
/*0927*/        (unsigned short*)
/*0928*/        callocObject(vFrameSize * sizeof(unsigned short), GCT_NOPOINTERS));
/*0929*/    vSP = 0;                   /* initial stack is empty. */
/*0930*/
/*0946*/    {
/*0947*/        /* Verify that all exception handlers have a reasonable value in 
/*0948./         * the exception flag.
/*0949./         */
/*0950*/        HANDLERTABLE handlers = thisMethod->u.java.handlers;
/*0951*/        if (handlers) {
/*0952*/            unsigned short exceptionClassKey;
/*0953*/            int i;
/*0954*/            for (i = 0; i < handlers->length; i++) {
/*0955*/                index = handlers->handlers[i].exception;
/*0956*/                if (index) {
/*0957*/                    CHECK_VALID_CP_INDEX(constPool, index);
/*0958*/                    tag = CONSTANTPOOL_MASKED_TAG(constPool, index);
/*0959*/                    if (tag != CONSTANT_Class) {
/*0960*/                        VERIFIER_ERROR(VE_EXPECT_CLASS);
/*0961*/                    }
/*0962*/                    exceptionClassKey =GET_CLASS_CONSTANT_KEY(constPool, index);
/*0963*/                    if (!vIsAssignable(exceptionClassKey, throwableClassKey,
/*0964*/                                       NULL)) {
/*0965*/                        VERIFIER_ERROR(VE_EXPECT_THROWABLE);
/*0966*/                    }
/*0967*/                } 
/*0968*/            }
/*0969*/        }
/*0970*/    }
/*0971*/
/*0972*/    {
/*0973*/        /* Fill in the initial derived stack map with argument types. */
/*0974*/        unsigned char *sig = (unsigned char*)
/*0975*/            change_Key_to_Name(thisMethod->nameTypeKey.nt.typeKey, NULL);
/*0976*/        int nargs = *sig++;
/*0977*/        int i;
/*0978*/        int n;
/*0979*/
/*0980*/        n = 0;
/*0981*/        if (!(thisMethod->accessFlags & ACC_STATIC)) {
/*0982*/            /* add one extra argument for instance methods */
/*0983*/            n++;
/*0984*/            if (thisMethod->nameTypeKey.nt.nameKey == initNameAndType.nt.nameKey &&
/*0985*/                thisMethod->ofClass->clazz.key != objectClassKey) {
/*0986*/                vLocals[0] = ITEM_InitObject;
/*0987*/            } else {
/*0988*/                vLocals[0] = thisMethod->ofClass->clazz.key;
/*0989*/            }

⌨️ 快捷键说明

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