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

📄 loader.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 2 页
字号:
/*0001*//*
/*0002./ * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
/*0003./ * 
/*0004./ * This software is the confidential and proprietary information of Sun
/*0005./ * Microsystems, Inc. ("Confidential Information").  You shall not
/*0006./ * disclose such Confidential Information and shall use it only in
/*0007./ * accordance with the terms of the license agreement you entered into
/*0008./ * with Sun.
/*0009./ * 
/*0010./ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
/*0011./ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/*0012./ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/*0013./ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
/*0014./ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
/*0015./ * THIS SOFTWARE OR ITS DERIVATIVES.
/*0016./ * 
/*0017./ */
/*0018*/
/*0019*//*=========================================================================
/*0020./ * SYSTEM:    KVM
/*0021./ * SUBSYSTEM: Class loader
/*0022./ * FILE:      loader.c
/*0023./ * OVERVIEW:  Structures and operations needed for loading
/*0024./ *            Java classfiles (class loader).
/*0025./ * AUTHOR:    Antero Taivalsaari, Sun Labs
/*0026./ *            Edited by Doug Simon 11/1998
/*0027./ *            Extensive changes for spec-compliance by Sheng Liang
/*0028./ *            Frank Yellin (lots of additional checks for JLS (Java
/*0029./ *            Language Spec) compliance)
/*0030./ *=======================================================================*/
/*0031*/
/*0032*//*=========================================================================
/*0033./ * Include files
/*0034./ *=======================================================================*/
/*0035*/
/*0036*/#include <global.h>
/*0037*/
/*0038*//*=========================================================================
/*0039./ * Macros and constants
/*0040./ *=======================================================================*/
/*0041*/
/*0042*/#define STRING_POOL(i)   (*((char **)(&StringPool->data[i])))
/*0043*/
/*0044*/#define RECOGNIZED_CLASS_FLAGS (ACC_PUBLIC | \
/*0045*/                    ACC_FINAL | \
/*0046*/                    ACC_SUPER | \
/*0047*/                    ACC_INTERFACE | \
/*0048*/                    ACC_ABSTRACT)    
/*0049*/       
/*0050*/#define RECOGNIZED_FIELD_FLAGS (ACC_PUBLIC | \
/*0051*/                    ACC_PRIVATE | \
/*0052*/                    ACC_PROTECTED | \
/*0053*/                    ACC_STATIC | \
/*0054*/                    ACC_FINAL | \
/*0055*/                    ACC_VOLATILE | \
/*0056*/                    ACC_TRANSIENT)
/*0057*/
/*0058*/#define RECOGNIZED_METHOD_FLAGS (ACC_PUBLIC | \
/*0059*/                     ACC_PRIVATE | \
/*0060*/                     ACC_PROTECTED | \
/*0061*/                     ACC_STATIC | \
/*0062*/                     ACC_FINAL | \
/*0063*/                     ACC_SYNCHRONIZED | \
/*0064*/                     ACC_NATIVE | \
/*0065*/                     ACC_ABSTRACT )
/*0066*/
/*0067*//*=========================================================================
/*0068./ * Static functions (used only in this file)
/*0069./ *=======================================================================*/
/*0070*/
/*0071*/#if USESTATIC
/*0072*/static void moveClassFieldsToStatic(INSTANCE_CLASS CurrentClass);
/*0073*/#else
/*0074*/# define moveClassFieldsToStatic(CurrentClass)
/*0075*/#endif
/*0076*/
/*0077*/static void ignoreAttributes(FILEPOINTER_HANDLE ClassFile, 
/*0078*/                             POINTERLIST_HANDLE StringPool);
/*0079*/
/*0080*/static void NoClassDefFoundError(INSTANCE_CLASS thisClass);
/*0081*/
/*0082*//*=========================================================================
/*0083./ * Class file verification operations (performed during class loading)
/*0084./ *=======================================================================*/
/*0085*/
/*0086*//*=========================================================================
/*0087./ * FUNCTION:      skipOverFieldName()
/*0088./ * TYPE:          private class file load operation
/*0089./ * OVERVIEW:      skip over a legal field name in a get a given string
/*0090./ * INTERFACE:
/*0091./ *   parameters:  string: a string in which the field name is skipped
/*0092./ *                slash_okay: is '/' OK.
/*0093./ *                length: length of the string
/*0094./ *   returns:     what's remaining after skipping the field name
/*0095./ *=======================================================================*/
/*0096*/
/*0097*/static const char *
/*0098*/skipOverFieldName(const char *string, bool_t slash_okay, unsigned short length)
/*0099*/{
/*0100*/    const char *p;
/*0101*/    unsigned short ch;
/*0102*/    unsigned short last_ch = 0;
/*0103*/    /* last_ch == 0 implies we are looking at the first char. */
/*0104*/    for (p = string; p != string + length; last_ch = ch) {
/*0105*/        const char *old_p = p;
/*0106*/        ch = *p;
/*0107*/        if (ch < 128) {
/*0108*/            p++;
/*0109*/            /* quick check for ascii */
/*0110*/            if ((ch >= 'a' && ch <= 'z') ||
/*0111*/                (ch >= 'A' && ch <= 'Z') ||
/*0112*/                (last_ch && ch >= '0' && ch <= '9')) {
/*0113*/                continue;
/*0114*/            }
/*0115*/        } else {
/*0116*/            /* KVM simplification: we give up checking for those Unicode
/*0117./               chars larger than 127. Otherwise we'll have to include a
/*0118./               couple of large Unicode tables, bloating the footprint by
/*0119./               8~10K. */
/*0120*/            const char *tmp_p = p;
/*0121*/            ch = utf2unicode((const char**)&tmp_p);
/*0122*/            p = tmp_p;
/*0123*/            continue;
/*0124*/        }
/*0125*/
/*0126*/        if (slash_okay && ch == '/' && last_ch) {
/*0127*/            if (last_ch == '/') {
/*0128*/                return NULL;    /* Don't permit consecutive slashes */
/*0129*/            }
/*0130*/        } else if (ch == '_' || ch == '$') {
/*0131*/            /* continue */
/*0132*/        } else {
/*0133*/            return last_ch ? old_p : NULL;
/*0134*/        }
/*0135*/    }
/*0136*/    return last_ch ? p : NULL;
/*0137*/}
/*0138*/
/*0139*//*=========================================================================
/*0140./ * FUNCTION:      skipOverFieldType()
/*0141./ * TYPE:          private class file load operation
/*0142./ * OVERVIEW:      skip over a legal field signature in a get a given string
/*0143./ * INTERFACE:
/*0144./ *   parameters:  string: a string in which the field signature is skipped
/*0145./ *                slash_okay: is '/' OK.
/*0146./ *                length: length of the string
/*0147./ *   returns:     what's remaining after skipping the field signature
/*0148./ *=======================================================================*/
/*0149*/
/*0150*/static const char *
/*0151*/skipOverFieldType(const char *string, bool_t void_okay, unsigned short length)
/*0152*/{
/*0153*/    unsigned int depth = 0;
/*0154*/    for (;length > 0;) {
/*0155*/        switch (string[0]) {
/*0156*/        case 'V':
/*0157*/            if (!void_okay) return NULL;
/*0158*/            /* FALL THROUGH */
/*0159*/        case 'Z':
/*0160*/        case 'B':
/*0161*/        case 'C':
/*0162*/        case 'S':
/*0163*/        case 'I':
/*0164*/        case 'J':
/*0165*/#if IMPLEMENTS_FLOAT
/*0166*/        case 'F':
/*0167*/        case 'D':
/*0168*/#endif
/*0169*/            return string + 1;
/*0170*/
/*0171*/        case 'L': {
/*0172*/            /* Skip over the class name, if one is there. */
/*0173*/            const char *p = skipOverFieldName((const char *) (string + 1), 
/*0174*/                                           TRUE, (unsigned short) (length - 1));
/*0175*/            /* The next character better be a semicolon. */
/*0176*/            if (p != NULL && p < string + length && p[0] == ';') { 
/*0177*/                return p + 1;
/*0178*/            } 
/*0179*/            return NULL;
/*0180*/        }
/*0181*/        
/*0182*/        case '[':
/*0183*/            /* The rest of what's there better be a legal signature.  */
/*0184*/            string++;
/*0185*/            length--;
/*0186*/            if (++depth == 256) { 
/*0187*/                return NULL;
/*0188*/            }
/*0189*/            void_okay = FALSE;
/*0190*/            break;
/*0191*/
/*0192*/        default:
/*0193*/            return NULL;
/*0194*/        }
/*0195*/    }
/*0196*/    return NULL;
/*0197*/}
/*0198*/
/*0199*//*=========================================================================
/*0200./ * FUNCTION:      getUTF8String()
/*0201./ * TYPE:          private class file load operation
/*0202./ * OVERVIEW:      get a UTF8 string from string pool, check index validity
/*0203./ * INTERFACE:
/*0204./ *   parameters:  String pool, index
/*0205./ *   returns:     Pointer to UTF8 string
/*0206./ *=======================================================================*/
/*0207*/
/*0208*/static char *
/*0209*/getUTF8String(POINTERLIST_HANDLE StringPoolH, unsigned short index)
/*0210*/{
/*0211*/    POINTERLIST StringPool = unhand(StringPoolH);
/*0212*/    if (index >= StringPool->length ||
/*0213*/        STRING_POOL(index) == NULL) {
/*0214*/        fatalError(KVM_MSG_BAD_UTF8_INDEX);
/*0215*/    }
/*0216*/    return STRING_POOL(index);
/*0217*/}
/*0218*/
/*0219*//*=========================================================================
/*0220./ * FUNCTION:      verifyUTF8String()
/*0221./ * TYPE:          private class file load operation
/*0222./ * OVERVIEW:      validate a UTF8 string
/*0223./ * INTERFACE:
/*0224./ *   parameters:  pointer to UTF8 string
/*0225./ *   returns:     nothing
/*0226./ *=======================================================================*/
/*0227*/
/*0228*/static void
/*0229*/verifyUTF8String(char* bytes, unsigned short length)
/*0230*/{
/*0231*/    int i;
/*0232*/    for (i=0; i<length; i++) {
/*0233*/        unsigned int c = ((unsigned char *)bytes)[i];
/*0234*/        if (c == 0) /* no embedded zeros */
/*0235*/            goto failed;
/*0236*/        if (c < 128)
/*0237*/            continue;
/*0238*/        switch (c >> 4) {
/*0239*/        default:
/*0240*/            break;
/*0241*/
/*0242*/        case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
/*0243*/            goto failed;
/*0244*/            
/*0245*/        case 0xC: case 0xD: 
/*0246*/            /* 110xxxxx  10xxxxxx */
/*0247*/            i++;
/*0248*/            if (i >= length)
/*0249*/                goto failed;
/*0250*/            if ((bytes[i] & 0xC0) == 0x80)
/*0251*/                break;
/*0252*/            goto failed;
/*0253*/            
/*0254*/        case 0xE:
/*0255*/            /* 1110xxxx 10xxxxxx 10xxxxxx */
/*0256*/            i += 2;
/*0257*/            if (i >= length)
/*0258*/                goto failed;
/*0259*/            if (((bytes[i-1] & 0xC0) == 0x80) &&
/*0260*/                ((bytes[i] & 0xC0) == 0x80))
/*0261*/                break;
/*0262*/            goto failed;
/*0263*/        } /* end of switch */
/*0264*/    }
/*0265*/    return;
/*0266*/
/*0267*/ failed:
/*0268*/    fatalError(KVM_MSG_BAD_UTF8_STRING);
/*0269*/}

⌨️ 快捷键说明

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