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

📄 classloader.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 4 页
字号:
unsigned Signature2ArgsSize(char *method_signature){    char *p;    int args_size = 0;    for (p = method_signature; *p != SIGNATURE_ENDFUNC; p++) {        switch (*p) {            case SIGNATURE_FLOAT:                if (no_floating_point) {                    panic("floating-point arguments should not appear");                }            case SIGNATURE_BOOLEAN:            case SIGNATURE_BYTE:            case SIGNATURE_CHAR:            case SIGNATURE_SHORT:            case SIGNATURE_INT:                args_size += 1;                break;            case SIGNATURE_CLASS:                args_size += 1;                while (*p != SIGNATURE_ENDCLASS) p++;                break;            case SIGNATURE_ARRAY:                args_size += 1;                while ((*p == SIGNATURE_ARRAY)) p++;                    /* If an array of classes, skip over class name, too. */                    if (*p == SIGNATURE_CLASS) {                        while (*p != SIGNATURE_ENDCLASS)                            p++;                    }                break;            case SIGNATURE_DOUBLE:                if (no_floating_point) {                    panic("floating-point arguments should not appear");                }            case SIGNATURE_LONG:                args_size += 2;                break;            case SIGNATURE_FUNC:  /* ignore initial (, if given */                break;            default:              /* Indicates an error. */                return 0;        }    }    return args_size;}/*========================================================================= * FUNCTION:      free_clinit_memory * OVERVIEW:      Frees clinit memory. * * INTERFACE: *   parameters:  struct methodblock *: mb * *   returns:     nothing *=======================================================================*/void free_clinit_memory(struct methodblock *mb){    /* This function is somewhat a hack. It fixes the problem in 1.1.3     * and before. sysFree may be called on the wrong memory block if     * the exception attribute comes before the code attribute.     */    /* If there is no exceptions attribute, or if both have already     * been freed.     */    if (mb->exceptions == NULL) {        if (mb->code) {            sysFree(mb->code);            mb->code = NULL;        }        return;    }    /* If both attributes exist, free the one at the lower address */    if ((char *)mb->code < (char *)mb->exceptions)        sysFree(mb->code);    else        sysFree(mb->exceptions);    mb->code = NULL;    mb->exceptions = NULL;}/*========================================================================= * FUNCTION:      FreeClass * OVERVIEW:      Frees class. * * INTERFACE: *   parameters:  ClassClass *: cb * *   returns:     nothing *=======================================================================*/void FreeClass(ClassClass *cb){    int i;    struct methodblock *mb;    for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {        if (strcmp(mb->fb.name, "<clinit>") == 0 &&            strcmp(mb->fb.signature, "()V") == 0 &&            mb->code_length /* not external */ )            free_clinit_memory(mb);    }    sysFree(cbConstantPool(cb));    sysFree(cbMethodTableMem(cb));    sysFree(cbSlotTable(cb));    /* Interface method tables can be shared between child and     * super classes.     */    if (cbImplementsCount(cb) != 0 || cbIsInterface(cb))        sysFree(cbIntfMethodTable(cb));}/*========================================================================= * FUNCTION:      get1byte * OVERVIEW:      Gets one byte from the class file. * * INTERFACE: *   parameters:  CICcontext *: context * *   returns:     value read or 0 if an error occurred. *=======================================================================*/static unsigned char get1byte(CICcontext *context){    unsigned char *ptr = context->ptr;    if (context->end_ptr - ptr < 1) {        JAVA_ERROR(context, "Truncated class file");        return 0;    } else {        unsigned char *ptr = context->ptr;        unsigned char value = ptr[0];        (context->ptr) += 1;        return value;    }}/*========================================================================= * FUNCTION:      get2bytes * OVERVIEW:      Gets two bytes from the class file. * * INTERFACE: *   parameters:  CICcontext *: context * *   returns:     value read or 0 if an error occurred. *=======================================================================*/static unsigned short get2bytes(CICcontext *context){    unsigned char *ptr = context->ptr;    if (context->end_ptr - ptr < 2) {        JAVA_ERROR(context, "Truncated class file");        return 0;    } else {        unsigned short value = (ptr[0] << 8) + ptr[1];        (context->ptr) += 2;        return value;    }}/*========================================================================= * FUNCTION:      get4bytes * OVERVIEW:      Gets four bytes from the class file. * * INTERFACE: *   parameters:  CICcontext *: context * *   returns:     value read or 0 if an error occurred. *=======================================================================*/static unsigned long get4bytes(CICcontext *context){    unsigned char *ptr = context->ptr;    if (context->end_ptr - ptr < 4) {        JAVA_ERROR(context, "Truncated class file");        return 0;    } else {        unsigned long value = (ptr[0] << 24) + (ptr[1] << 16) +                                 (ptr[2] << 8) + ptr[3];        (context->ptr) += 4;        return value;    }}/*========================================================================= * FUNCTION:      getNbytes * OVERVIEW:      Gets N bytes from the class file specified by the count *                parameter. If buffer is not null, it will also copy the *                count number of bytes read into the buffer as well. *                Note that this function seems to be always invoked with *                a NULL argument for the buffer, except when it loads the *                UTF8 entry from the constant pool and when the code *                attribute is loaded. * * INTERFACE: *   parameters:  CICcontext *: context *                int: count *                char *: buffer * *   returns:     nothing *=======================================================================*/static void getNbytes(CICcontext *context, int count, char *buffer){    unsigned char *ptr = context->ptr;    if (context->end_ptr - ptr < count)        JAVA_ERROR(context, "Truncated class file");    if (buffer != NULL)        memcpy(buffer, ptr, count);    (context->ptr) += count;}/*========================================================================= * FUNCTION:      getAsciz * OVERVIEW:      Reads the next two bytes and uses this value to look up for *                the corresponding constant pool entry. *                Returns null if the value is 0 and zeroOkay flag is set. * * INTERFACE: *   parameters:  CICcontext *: context *                bool_t : zeroOkay * *   returns:     char * or NULL *=======================================================================*/static char *getAsciz(CICcontext *context, bool_t zeroOkay){    ClassClass *cb = context->cb;    union cp_item_type *constant_pool = cbConstantPool(cb);    int nconstants = cbConstantPoolCount(cb);    unsigned char *type_table =        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;    int value = get2bytes(context);    if (value == 0 && zeroOkay) {        return NULL;    } else if ((value == 0) || (value >= nconstants) ||        type_table[value] != (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED))        JAVA_ERROR(context, "Illegal constant pool index");    return constant_pool[value].cp;}/*========================================================================= * FUNCTION:      getAscizFromClass * OVERVIEW:      Given the constant pool index, returns the name of the class *                which corresponds to this constant pool entry. * * INTERFACE: *   parameters:  CICcontext *: context *                int: value * *   returns:     char * or NULL *=======================================================================*/static char *getAscizFromClass(CICcontext *context, int value){    ClassClass *cb = context->cb;    union cp_item_type *constant_pool = cbConstantPool(cb);    int nconstants = cbConstantPoolCount(cb);    unsigned char *type_table =    constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;    if ((value > 0) && (value < nconstants)) {        if (type_table[value] == CONSTANT_Class) {            value = constant_pool[value].i;            if ((value <= 0) || (value >= nconstants) ||                (type_table[value] != (CONSTANT_Utf8 |                       CONSTANT_POOL_ENTRY_RESOLVED)))                JAVA_ERROR(context, "Illegal constant pool index");            return constant_pool[value].cp;        } else if (type_table[value] == (CONSTANT_Class |                                 CONSTANT_POOL_ENTRY_RESOLVED)) {            ClassClass *cb = constant_pool[value].clazz;            return cbName(cb);        } else {            JAVA_ERROR(context, "Illegal constant pool index");        }    } else {        JAVA_ERROR(context, "Illegal constant pool index");    }    return NULL; /* not reached */}/* In order to avoid possible alignment errors, round up all sizes to * multiples of eight. */#define ROUNDUP_SIZE(s) while ((s) % 8 != 0) (s)++/*========================================================================= * FUNCTION:      allocNBytes * OVERVIEW:      Memory allocation function for internal class file *                structures. *                It calculates the number of allocations needed for the *                two passes, and the allocations required for the clinit *                method. * * INTERFACE: *   parameters:  CICcontext *: context *                int : size * *   returns:     void * *=======================================================================*/static void *allocNBytes(CICcontext *context, int size){    void *result;    if (context->pass == 1) {        /* The first pass         * A more sophisticated scheme could reduce the number of mallocs.         */        CICmallocs *mallocs =           (CICmallocs *)sysCalloc(1, sizeof(CICmallocs) + size);        if (mallocs == 0)            JAVA_ERROR(context, "out of memory");        result = (void *)(mallocs + 1);        mallocs->next = context->pass1.mallocs;        ROUNDUP_SIZE(size);        if (context->in_clinit)            context->clinit_size += size;        else            context->malloc_size += size;        context->pass1.mallocs = mallocs;    } else {        /* The second pass */        ROUNDUP_SIZE(size);#define ALLOC_BLOCK(ptr,buf,sizelimit)     \        result = (ptr);                    \        (ptr) += (size);                   \        sysAssert((ptr) <= (buf) + (sizelimit))        if (context->in_clinit) {            /* Make sure that this clinit pointer is not null */            sysAssert(context->pass2.clinit_ptr != NULL);            ALLOC_BLOCK(context->pass2.clinit_ptr,            context->pass2.clinit_buffer,            context->clinit_size*sizeof(char));        } else {            /* Make sure that this malloc pointer is not null */            sysAssert(context->pass2.malloc_ptr != NULL);            ALLOC_BLOCK(context->pass2.malloc_ptr,            context->pass2.malloc_buffer,            context->malloc_size);        }    }    return result;}/*========================================================================= * FUNCTION:      freeBuffers * OVERVIEW:      Frees buffers allocated by allocNBytes(). * * INTERFACE: *   parameters:  CICcontext *: context * *   returns:     nothing *=======================================================================*/static void freeBuffers(CICcontext * context){    if (context->pass == 1) {        CICmallocs *mallocs = context->pass1.mallocs;        while (mallocs) {            CICmallocs *tmp = mallocs;            mallocs = mallocs->next;            if (tmp != NULL) {                sysFree(tmp);            }        }        context->pass1.mallocs = 0;    } else { /* context->pass = 2 *//* Note: this code is here just for historical reasons. Actually, these * buffers cannot really be freed here since the data in them is still * pointed to by the class buffer (cb) and we are not yet done loading * the class. If the class loading fails, FreeClass() will free the method * blocks and the clinit memory. */        if (context->pass2.malloc_buffer != NULL) {            sysFree(context->pass2.malloc_buffer);            /* Reset only if buffer was freed */            context->pass2.malloc_buffer = 0;        }        if (context->pass2.clinit_buffer != NULL) {            sysFree(context->pass2.clinit_buffer);            /* Initialize only if buffer was freed */            context->pass2.clinit_buffer = 0;        }    }}/*========================================================================= * FUNCTION:      GetClassConstantClassName * OVERVIEW:      Returns class name corresponding to the constant pool entry *                for the given cpIndex. This is desirable in cases when we *                may simply be interested in the name of the class, but may *                not necessarily want to resolve the class reference if it *                isn't already. * * INTERFACE: *   parameters:  cp_item_type *: constant pool *                int : index * *   returns:     char *: class name *=======================================================================*/char *GetClassConstantClassName(cp_item_type *constant_pool, int index){    unsigned char *type_table =        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;    switch(type_table[index]) {        case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED: {            ClassClass *cb = constant_pool[index].clazz;            return cbName(cb);        }        case CONSTANT_Class: {            int name_index = constant_pool[index].i;            return constant_pool[name_index].cp;        }        default:            return (char *)0;    }}

⌨️ 快捷键说明

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