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

📄 fields.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: Internal runtime structures
/*0022./ * FILE:      fields.c
/*0023./ * OVERVIEW:  Internal runtime structures for storing different kinds 
/*0024./ *            of fields (constants, variables, methods, interfaces).
/*0025./ *            Tables of these fields are created every time a new class
/*0026./ *            is loaded into the virtual machine.
/*0027./ * AUTHOR:    Antero Taivalsaari, Sun Labs
/*0028./ *            Edited by Doug Simon 11/1998
/*0029./ *            Sheng Liang, Frank Yellin
/*0030./ *=======================================================================*/
/*0031*/
/*0032*//*=========================================================================
/*0033./ * Include files
/*0034./ *=======================================================================*/
/*0035*/
/*0036*/#include <global.h>
/*0037*/
/*0038*//*=========================================================================
/*0039./ * Static variables and definitions (specific to this file)
/*0040./ *=======================================================================*/
/*0041*/
/*0042*/static void change_Key_to_MethodSignatureInternal(unsigned char**, char**);
/*0043*/static void change_MethodSignature_to_KeyInternal(CONST_CHAR_HANDLE, 
/*0044*/                                                  int *offsetP, 
/*0045*/                                                  unsigned char **to);
/*0046*/
/*0047*//*=========================================================================
/*0048./ * Operations on field and method tables
/*0049./ *=======================================================================*/
/*0050*/
/*0051*//*=========================================================================
/*0052./ * FUNCTION:      lookupField()
/*0053./ * TYPE:          public instance-level operation
/*0054./ * OVERVIEW:      Find a field table entry with the given field name.
/*0055./ * INTERFACE:
/*0056./ *   parameters:  class pointer, field name pointer
/*0057./ *   returns:     pointer to the field or NIL
/*0058./ *=======================================================================*/
/*0059*/
/*0060*/FIELD lookupField(INSTANCE_CLASS thisClass, NameTypeKey key) { 
/*0061*/    do { 
/*0062*/        FIELDTABLE fieldTable = thisClass->fieldTable;
/*0063*/        /*  Get the length of the field table */
/*0064*/        FOR_EACH_FIELD(thisField, fieldTable) 
/*0065*/            if (thisField->nameTypeKey.i == key.i) { 
/*0066*/                return thisField;
/*0067*/            }
/*0068*/        END_FOR_EACH_FIELD
/*0069*/            thisClass = thisClass->superClass;
/*0070*/    } while (thisClass != NULL);
/*0071*/    return NULL;
/*0072*/}
/*0073*/
/*0074*//*=========================================================================
/*0075./ * FUNCTION:      lookupMethod()
/*0076./ * TYPE:          public instance-level operation
/*0077./ * OVERVIEW:      Find a method table entry with the given name and type
/*0078./ *                using a simple linear lookup strategy.
/*0079./ * INTERFACE:
/*0080./ *   parameters:  class pointer, method name and signature pointers
/*0081./ *   returns:     pointer to the method or NIL
/*0082./ *
/*0083./ * NOTES:         This is a naive implementation with linear search.
/*0084./ *                In most cases this does not matter, however, since
/*0085./ *                inline caching (turning ENABLEFASTBYTECODES on) 
/*0086./ *                allows us to avoid the method lookup overhead.
/*0087./ *=======================================================================*/
/*0088*/
/*0089*/METHOD lookupMethod(CLASS thisClass, NameTypeKey key, 
/*0090*/                    INSTANCE_CLASS currentClass)
/*0091*/{
/*0092*/    INSTANCE_CLASS thisInstanceClass = 
/*0093*/        IS_ARRAY_CLASS(thisClass) ? JavaLangObject : (INSTANCE_CLASS)thisClass;
/*0094*/    do {
/*0095*/        METHODTABLE methodTable = thisInstanceClass->methodTable;
/*0096*/        FOR_EACH_METHOD(thisMethod, methodTable) 
/*0097*/            if (thisMethod->nameTypeKey.i == key.i) { 
/*0098*/                if (   currentClass == NULL 
/*0099*/                    || currentClass == thisInstanceClass
/*0100*/                    || ((ACC_PUBLIC|ACC_PROTECTED) & thisMethod->accessFlags)
/*0101*/                    || ( ((thisMethod->accessFlags & ACC_PRIVATE) == 0)
/*0102*/                    && thisInstanceClass->clazz.packageName == 
/*0103*/                           currentClass->clazz.packageName)
/*0104*/                ) { 
/*0105*/                    return thisMethod;
/*0106*/                }
/*0107*/            }
/*0108*/        END_FOR_EACH_METHOD
/*0109*/            /*  If the class has a superclass, look its methods as well */
/*0110*/            thisInstanceClass = thisInstanceClass->superClass;
/*0111*/    } while (thisInstanceClass != NULL);
/*0112*/
/*0113*/    /* Before we give up on an interface class, check any interfaces that
/*0114./     * it implements */
/*0115*/    if ((thisClass->accessFlags & ACC_INTERFACE) 
/*0116*/        && (((INSTANCE_CLASS)thisClass)->ifaceTable != NULL)) {
/*0117*/        CONSTANTPOOL constantPool = ((INSTANCE_CLASS)thisClass)->constPool;
/*0118*/        unsigned short *ifaceTable = ((INSTANCE_CLASS)thisClass)->ifaceTable;
/*0119*/        int tableLength = ifaceTable[0];
/*0120*/        int i;
/*0121*/        for (i = 1; i <= tableLength; i++) {
/*0122*/            int cpIndex = ifaceTable[i];
/*0123*/            CLASS intf = constantPool->entries[cpIndex].clazz;
/*0124*/            METHOD temp = lookupMethod(intf, key, currentClass);
/*0125*/            if (temp != NULL) { 
/*0126*/                return temp;
/*0127*/            }
/*0128*/        }
/*0129*/    }
/*0130*/    return NULL;
/*0131*/}
/*0132*/
/*0133*//*=========================================================================
/*0134./ * FUNCTION:      getSpecialMethod()
/*0135./ * TYPE:          public instance-level operation
/*0136./ * OVERVIEW:      Find a specific special method (<clinit>, main)
/*0137./ *                using a simple linear lookup strategy.
/*0138./ * INTERFACE:
/*0139./ *   parameters:  class pointer, method name and signature pointers
/*0140./ *   returns:     pointer to the method or NIL
/*0141./ *=======================================================================*/
/*0142*/
/*0143*/METHOD getSpecialMethod(INSTANCE_CLASS thisClass, NameTypeKey key)
/*0144*/{
/*0145*/    METHODTABLE methodTable = thisClass->methodTable;
/*0146*/    FOR_EACH_METHOD(thisMethod, methodTable) 
/*0147*/        if (    (thisMethod->accessFlags & ACC_STATIC)
/*0148*/             && (thisMethod->nameTypeKey.i == key.i))
/*0149*/            return thisMethod;
/*0150*/    END_FOR_EACH_METHOD
/*0151*/    return NIL;
/*0152*/}
/*0153*/
/*0359*//*=========================================================================
/*0360./ * Internal operations on signatures
/*0361./ *=======================================================================*/
/*0362*/
/*0363*//*=========================================================================
/*0364./ * FUNCTION:      change_Key_to_FieldSignature()
/*0365./ *                change_Key_to_FieldSignature_inBuffer()
/*0366./ *
/*0367./ * TYPE:          public instance-level operation on runtime classes
/*0368./ * OVERVIEW:      Converts a FieldType key to its actual signature
/*0369./ *
/*0370./ * INTERFACE:
/*0371./ *   parameters:  key:           An existing FieldType key
/*0372./ *                resultBuffer:  Where to put the result
/*0373./ *
/*0374./ *   returns:     getClassName() returns a pointer to the result
/*0375./ *                getClassName_inBuffer() returns a pointer to the NULL
/*0376./ *                     at the end of the result.  The result is in the
/*0377./ *                     passed buffer.
/*0378./ * 
/*0379./ * DANGER:  change_Key_to_FieldSignature_inBuffer() doesn't return what you
/*0380./ *          expect.
/*0381./ *
/*0382./ *=======================================================================*/
/*0383*/
/*0384*/char *
/*0385*/change_Key_to_FieldSignature(FieldTypeKey key) { 
/*0386*/    char *endBuffer = change_Key_to_FieldSignature_inBuffer(key, str_buffer);
/*0387*/    int length = endBuffer - str_buffer;
/*0388*/    char *result = mallocBytes(length + 1);
/*0389*/    memcpy(result, str_buffer, length);
/*0390*/    result[length] = 0;
/*0391*/    return result;
/*0392*/}
/*0393*/
/*0394*/char*                   /* returns end of buffer */
/*0395*/change_Key_to_FieldSignature_inBuffer(FieldTypeKey key, char *resultBuffer) { 
/*0396*/    char *p          = resultBuffer;
/*0397*/    int depth        = key >> FIELD_KEY_ARRAY_SHIFT;
/*0398*/    FieldTypeKey baseClassKey = key & 0x1FFF;
/*0399*/    if (depth == MAX_FIELD_KEY_ARRAY_DEPTH) { 
/*0400*/        /* just use whatever the real classname is */
/*0401*/        return getClassName_inBuffer(change_Key_to_CLASS(key), resultBuffer);
/*0402*/    }
/*0403*/    if (depth > 0) { 
/*0404*/        memset(p, '[', depth);
/*0405*/        p += depth;
/*0406*/    }
/*0407*/    if (baseClassKey <= 255) { 
/*0408*/        *p++ = (char)baseClassKey;
/*0409*/    } else { 
/*0410*/        *p++ = 'L';
/*0411*/        p = getClassName_inBuffer(change_Key_to_CLASS(baseClassKey), p);
/*0412*/        *p++ = ';';
/*0413*/    } 
/*0414*/    *p = '\0';
/*0415*/    return p;
/*0416*/}
/*0417*/        
/*0418*//*=========================================================================
/*0419./ * FUNCTION:      change_Key_to_MethodSignature()
/*0420./ *                change_Key_to_MethodSignature_inBuffer()
/*0421./ *
/*0422./ * TYPE:          public instance-level operation on runtime classes
/*0423./ * OVERVIEW:      Converts a MethodType key to its actual signature
/*0424./ *
/*0425./ * INTERFACE:
/*0426./ *   parameters:  key:         An existing MethodType key
/*0427./ *                resultBuffer:  Where to put the result
/*0428./ *
/*0429./ *   returns:     getClassName() returns a pointer to the result
/*0430./ *                getClassName_inBuffer() returns a pointer to the NULL
/*0431./ *                     at the end of the result.  The result is in the
/*0432./ *                     passed buffer.
/*0433./ * 
/*0434./ * DANGER:  change_Key_to_MethodSignature_inBuffer() doesn't return what you
/*0435./ *          expect.
/*0436./ *
/*0437./ * DANGER:  change_Key_to_MethodSignature() allocates a byte array, and marks
/*0438./ *          this array as a temporary root.  This function should only be
/*0439./ *          called inside START_TEMPORARY_ROOTS ... END_TEMPORARY_ROOTS
/*0440./ *
/*0441./ * NOTE: The algorithm for converting a method signature to a key is
/*0442./ * explained in the documentation below for change_MethodSignature_to_Key()
/*0443./ *=======================================================================*/
/*0444*/
/*0445*/char *
/*0446*/change_Key_to_MethodSignature(MethodTypeKey key) 
/*0447*/{ 
/*0448*/    char *endBuffer = change_Key_to_MethodSignature_inBuffer(key, str_buffer);
/*0449*/    int length = endBuffer - str_buffer;
/*0450*/    char *result = mallocBytes(length + 1);
/*0451*/    memcpy(result, str_buffer, length);
/*0452*/    result[length] = 0;
/*0453*/    return result;
/*0454*/}
/*0455*/
/*0456*/char*                           /* returns end of string */
/*0457*/change_Key_to_MethodSignature_inBuffer(MethodTypeKey key, char *resultBuffer) {
/*0458*/    int  codedSignatureLength;
/*0459*/    unsigned char *codedSignature = 
/*0460*/        (unsigned char *)change_Key_to_Name(key, &codedSignatureLength);
/*0461*/
/*0462*/    unsigned char *from = codedSignature; /* for parsing the codedSignature */
/*0463*/    char *to = resultBuffer;    /* for writing to the result */
/*0464*/
/*0465*/    int  argCount = *from++;    /* the first byte is the arg count */
/*0466*/
/*0467*/    *to++ = '(';                /* message signatures start with '(' */
/*0468*/
/*0469*/    /* Parse the coded signature one argument at a time, and put the 
/*0470./     * resulting signature into the result.  "from" and "to" are updated. 
/*0471./     */
/*0472*/    while (--argCount >= 0) { 
/*0473*/        change_Key_to_MethodSignatureInternal(&from, &to);
/*0474*/    }
/*0475*/
/*0476*/    /* Now output the closing ')' */
/*0477*/    *to++ = ')';
/*0478*/
/*0479*/    /* And the return type */
/*0480*/    change_Key_to_MethodSignatureInternal(&from, &to);
/*0481*/
/*0482*/    /* And the closing NULL */
/*0483*/    *to = '\0';
/*0484*/
/*0485*/    /* Return the end of the string */
/*0486*/    return to;

⌨️ 快捷键说明

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