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

📄 fields.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 2 页
字号:
/*0487*/}
/*0488*/
/*0489*//* A helper function used above.  
/*0490./ *
/*0491./ * It expects the start of the signature of an argument or return type at
/*0492./ * *fromP.   It encodes that single argument. Both fromP, and toP are updated
/*0493./ * to point just past the argument just read/written.
/*0494./ */
/*0495*/static void
/*0496*/change_Key_to_MethodSignatureInternal(unsigned char **fromP, char **toP) { 
/*0497*/    unsigned char *from = *fromP;
/*0498*/    char *to = *toP;
/*0499*/    unsigned char tag = *from++;
/*0500*/
/*0501*/    /* normal tags represent themselves */
/*0502*/    if ((tag >= 'A' && tag <= 'Z') && (tag != 'L')) { 
/*0503*/        *to++ = (char)tag;
/*0504*/    } else { 
/*0505*/        FieldTypeKey classKey;
/*0506*/        if (tag == 'L') { 
/*0507*/            tag = *from++;
/*0508*/        }
/*0509*/        classKey = (((int)tag) << 8) + *from++;
/*0510*/        to = change_Key_to_FieldSignature_inBuffer(classKey, to);
/*0511*/    }
/*0512*/    *fromP = from;
/*0513*/    *toP = to;
/*0514*/}
/*0515*/
/*0516*//*=========================================================================
/*0517./ * FUNCTION:      change_FieldSignature_to_Key()
/*0518./ *
/*0519./ * TYPE:          public instance-level operation on runtime classes
/*0520./ *
/*0521./ * OVERVIEW:      Converts a field signature into a unique 16-bit value.
/*0522./ *
/*0523./ * INTERFACE:
/*0524./ *   parameters:  type:        A pointer to the field signature
/*0525./ *                length:      length of signature
/*0526./ *
/*0527./ *   returns:     The unique 16-bit key that represents this field type
/*0528./ * 
/*0529./ * The encoding is as follows:
/*0530./ *    0 - 255:    Primitive types.  These use the same encoding as signature.
/*0531./ *                For example:  int is 'I', boolean is 'Z', etc.
/*0532./ *
/*0533./ *  256 - 0x1FFF  Non-array classes.  Every class is assigned a unique 
/*0534./ *                key value when it is created.  This value is used.  
/*0535./ *
/*0536./ * 0x2000-0xDFFF  Arrays of depth 1 - 6.  The high three bits represent the
/*0537./ *                depth, the low 13-bits (0 - 0x1FFF) represent the type.
/*0538./ *
/*0539./ * 0xE000-0xFFFF  Arrays of depth 8 or more.  These are specially encoded
/*0540./ *                so that the low 13-bits are different that the low 13-bits
/*0541./ *                of any other class.  The high bits are set so that we'll
/*0542./ *                recognize it as an array.
/*0543./ *
/*0544./ * Note that this scheme lets us encode an array class with out actually
/*0545./ * creating it.
/*0546./ * 
/*0547./ * The algorithm that gives key codes to classes cooperates with this scheme.
/*0548./ * When an array class is ever created, it is given the appropriate key code.
/*0549./ *
/*0550./ * NOTE! [Sheng 1/30/00] The verifier now uses the 13th bit (0x1000) to
/*0551./ * indicate whether a class instance has been initialized (ITEM_NewObject).
/*0552./ * As a result, only the low 12 bits (0 - 0xFFF) represent the base class
/*0553./ * type.
/*0554./ * 
/*0555./ *=======================================================================*/
/*0556*/
/*0557*/FieldTypeKey
/*0558*/change_FieldSignature_to_Key (CONST_CHAR_HANDLE typeH, int offset, int length) {
/*0559*/    CLASS clazz;
/*0560*/    const char *start = unhand(typeH); /* volatile */
/*0561*/    const char *type = start + offset; /* volatile */
/*0562*/    const char *end = type + length;   /* volatile */
/*0563*/    const char *p = type;              /* volatile */
/*0564*/    
/*0565*/    int depth;
/*0566*/
/*0567*/    /* Get the depth, and skip over the initial '[' that indicate the */
/*0568*/
/*0569*/    while (*p == '[') { 
/*0570*/        p++;
/*0571*/    }
/*0572*/    depth = p - type;
/*0573*/
/*0574*/    /* Arrays of depth greater than 6 are just handled as if they were real
/*0575./     * classes.  They will automatically be assigned */
/*0576*/    if (depth >= MAX_FIELD_KEY_ARRAY_DEPTH) { 
/*0577*/        clazz = getRawClassX(typeH, offset, length);
/*0578*/        /* I haven't decided yet whether these classes' keys will actually 
/*0579./         * have their 3 high bits set to 7 or not.  The following will work
/*0580./         * in either case */
/*0581*/        return (clazz->key) | (short)(MAX_FIELD_KEY_ARRAY_DEPTH
/*0582*/               << FIELD_KEY_ARRAY_SHIFT);
/*0583*/    } else if (*p != 'L') { 
/*0584*/        /* We have a primitive type, or an array thereof (depth <
/*0585./           MAX_FIELD_KEY_ARRAY_DEPTH )
/*0586./        */
/*0587*/        return (*(unsigned char *)p) + (depth << FIELD_KEY_ARRAY_SHIFT);
/*0588*/    } else { 
/*0589*/        /* We have an object, or an array thereof.  With signatures, these
/*0590./         * always have an 'L' at the beginning, and a ';' at the end.  
/*0591./         * We're not checking that this is a well-formed signature, but we 
/*0592./         * could */
/*0593*/        p++;                    /* skip over 'L' for non-arrays */
/*0594*/        end--;                  /* ignore ; at the end */
/*0595*/        clazz = getRawClassX(typeH, p - start, end - p);
/*0596*/        return clazz->key + (depth << FIELD_KEY_ARRAY_SHIFT);
/*0597*/    }
/*0598*/} 
/*0599*/
/*0600*//*=========================================================================
/*0601./ * FUNCTION:      change_MethodSignature_to_Key()
/*0602./ *
/*0603./ * TYPE:          public instance-level operation on runtime classes
/*0604./ *
/*0605./ * OVERVIEW:      Converts a method signature into a unique 16-bit value.
/*0606./ *
/*0607./ * INTERFACE:
/*0608./ *   parameters:  type:        A pointer to the method signature
/*0609./ *                length:      length of signature
/*0610./ *
/*0611./ *   returns:     The unique 16-bit key that represents this field type
/*0612./ * 
/*0613./ * The encoding is as follows:
/*0614./ * 
/*0615./ * We first encode the method signature into an "encoded" signature.  This
/*0616./ * encoded signature is then treated as it were a name, and that name.  We
/*0617./ * call change_Name_to_Key on it. 
/*0618./ * 
/*0619./ * The character array is created as follows
/*0620./ *   1 byte indicates the number of arguments
/*0621./ *   1 - 3 bytes indicate the first argument
/*0622./ *       ..
/*0623./ *   1 - 3 bytes indicate the nth argument
/*0624./ *   1 - 3 bytes indicate the return type.
/*0625./ * 
/*0626./ *  % If the type is primitive, it is encoded using its signature, like 'I',
/*0627./ *    'B', etc.  
/*0628./ *  % Otherwise, we get its 16-bit class key.  
/*0629./ *     .  If the high byte is in the range 'A'..'Z', we encode it as the 3
/*0630./ *        bytes,:  'L', hi, lo
/*0631./ *     .  Otherwise, we encode it as the 2 byte, hi, lo
/*0632./ *
/*0633./ * We're saving the whole range 'A'..'Z' since we may want to make 'O' be
/*0634./ * java.lang.Object, or 'X' be java.lang.String. . . .
/*0635./ * 
/*0636./ * Note that the first argument indicates slots, not arguments.  doubles and
/*0637./ * longs are two slots.
/*0638./ *=======================================================================*/
/*0639*/
/*0640*/FieldTypeKey 
/*0641*/change_MethodSignature_to_Key(CONST_CHAR_HANDLE nameH, int offset, int length)
/*0642*/{
/*0643*/
/*0644*/    /* We're first going to encode the signature, as indicated above. */
/*0645*/    unsigned char *buffer = (unsigned char *)str_buffer;/* temporary storage */
/*0646*/
/*0647*/    /* unhand(nameH)[fromOffset] points into signature */
/*0648*/    int fromOffset = offset + 1;
/*0649*/
/*0650*/    unsigned char *to = buffer + 1; /* pointer into encoding */
/*0651*/    int argCount = 0;
/*0652*/    int result;
/*0653*/
/*0654*/    /* Call a helper function to do the actual work.  This help function
/*0655./     * converts one field into its encoding.  fromOffset and to are updated.  
/*0656./     * The function returns the number of slots of its argument */
/*0657*/    while (unhand(nameH)[fromOffset] != ')') { 
/*0658*/        /* The following may GC */
/*0659*/        change_MethodSignature_to_KeyInternal(nameH, &fromOffset, &to);
/*0660*/        argCount++;
/*0661*/    }
/*0662*/
/*0663*/    /* Skip over the ')' */
/*0664*/    fromOffset++;
/*0665*/
/*0666*/    /* And interpret the return type, too */
/*0667*/    change_MethodSignature_to_KeyInternal(nameH, &fromOffset, &to);
/*0668*/    
/*0669*/    /* Set the slot type. */
/*0670*/    buffer[0] = argCount;
/*0671*/    if (fromOffset != offset + length) { 
/*0672*/        /* We should have exactly reached the end of the string */
/*0673*/        fatalError(KVM_MSG_BAD_METHOD_SIGNATURE);
/*0674*/    }
/*0675*/
/*0676*/    /* And get the name key for the encoded signature */
/*0677*/    result = change_Name_to_Key((CONST_CHAR_HANDLE)&buffer, 0, to - buffer);
/*0678*/    return result;
/*0679*/}
/*0680*/
/*0681*//* Helper function used by the above function.  It parses the single field
/*0682./ * signature starting at *fromP, and puts the result at *toP.  Both are
/*0683./ * updated to just past where they were.  The size of the argument is returned.
/*0684./ */
/*0685*/
/*0686*/static void
/*0687*/change_MethodSignature_to_KeyInternal(CONST_CHAR_HANDLE nameH, 
/*0688*/                                      int *fromOffsetP, unsigned char **toP)
/*0689*/{
/*0690*/    const char *start = unhand(nameH);
/*0691*/    const int fromOffset = *fromOffsetP;
/*0692*/    const char  *const from = start + fromOffset;
/*0693*/    unsigned char *to = *toP;
/*0694*/    const char *endFrom;
/*0695*/    
/*0696*/    switch (*from) { 
/*0697*/        default:
/*0698*/            endFrom = from + 1;
/*0699*/            break;
/*0700*/        case 'L':
/*0701*/            endFrom = strchr(from + 1, ';') + 1;
/*0702*/            break;
/*0703*/        case '[':
/*0704*/            endFrom = from + 1;
/*0705*/            while (*endFrom == '[') endFrom++;
/*0706*/            if (*endFrom == 'L') { 
/*0707*/                endFrom = strchr(endFrom + 1, ';') + 1;             
/*0708*/            } else { 
/*0709*/                endFrom++;
/*0710*/            }
/*0711*/            break;
/*0712*/    }
/*0713*/    if (endFrom == from + 1) { 
/*0714*/        *to++ = (unsigned char)*from;
/*0715*/    } else { 
/*0716*/        FieldTypeKey key = change_FieldSignature_to_Key(nameH, from - start, 
/*0717*/                                                        endFrom - from);
/*0718*/        unsigned char hiChar = ((unsigned)key) >> 8;
/*0719*/        unsigned char loChar = key & 0xFF;
/*0720*/        if (hiChar >= 'A' && hiChar <= 'Z') { 
/*0721*/            *to++ = 'L';
/*0722*/        }
/*0723*/        *to++ = hiChar;
/*0724*/        *to++ = loChar;
/*0725*/    }
/*0726*/    *to = '\0';                 /* always helps debugging */
/*0727*/    *toP = to;
/*0728*/    /* Although from and endfrom are no longer valid, their difference is
/*0729./     * still the amount by which fromOffset has increased
/*0730./     */
/*0731*/    *fromOffsetP = fromOffset + (endFrom - from);
/*0732*/}
/*0733*/
/*0734*//*=========================================================================
/*0735./ * FUNCTION:      getNameAndTypeKey
/*0736./ *
/*0737./ * OVERVIEW:      converts a name and signature (either field or method) to 
/*0738./ *                a 32bit value. 
/*0739./ *
/*0740./ * INTERFACE:
/*0741./ *   parameters:  name:      Name of method
/*0742./ *                type:      Field or method signature.
/*0743./ *
/*0744./ *   returns:     The unique 32-bit value that represents the name and type.
/*0745./ * 
/*0746./ * We use a structure with two 16-bit values.  One 16-bit value encodes the
/*0747./ * name using standard name encoding.  The other holds the key of the
/*0748./ * signature.
/*0749./ * 
/*0750./ * Note that we cannot do the reverse operation.  Given a type key, we can't
/*0751./ * tell if its a method key or a field key!
/*0752./ *=======================================================================*/
/*0753*/
/*0754*/NameTypeKey 
/*0755*/getNameAndTypeKey(const char *name, const char *type) {
/*0756*/    int typeLength = strlen(type);
/*0757*/    NameTypeKey result;
/*0761*/    result.nt.nameKey = getUString(name)->key;
/*0762*/    result.nt.typeKey = ((type)[0] == '(')
/*0763*/              ? change_MethodSignature_to_Key(&type, 0, typeLength)
/*0764*/              : change_FieldSignature_to_Key(&type, 0, typeLength);
/*0765*/    return result;
/*0766*/}
/*0767*/
/*0768*/

⌨️ 快捷键说明

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