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

📄 classloader.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 4 页
字号:
            ucb->source_name = getAsciz(context, FALSE);        } else if (strcmp(attr_name, "AbsoluteSourcePath") == 0) {            if (length == 2) {                ucb->absolute_source_name = getAsciz(context, FALSE);            } else            getNbytes(context, length, NULL);        } else if (strcmp(attr_name, "TimeStamp") == 0) {            if (length == 8) {                ucb->hasTimeStamp = TRUE;                ucb->timestamp.high = get4bytes(context);                ucb->timestamp.low = get4bytes(context);            } else {                getNbytes(context, length, NULL);            }        } else if (strcmp(attr_name, "Deprecated") == 0) {            if (length > 0) {                JAVA_ERROR(context, "Bad deprecated size");            }            ucb->deprecated = TRUE;        } else if (strcmp(attr_name, "Synthetic") == 0) {            if (length > 0) {                JAVA_ERROR(context, "Bad synthetic attribute size");            }            ucb->synthetic = TRUE;        } else if (strcmp(attr_name, "InnerClasses") == 0) {            int count = get2bytes(context);            struct innerClasses *thisInnerClass = (struct innerClasses *)                 allocNBytes(context, count * sizeof(struct innerClasses));            struct innerClasses *lastInnerClass = thisInnerClass + count;            if (count * 8 + 2 != length) {                JAVA_ERROR(context, "Bad length of InnerClasses attribute");            }            ucb->inner_classes_count = count;            ucb->inner_classes = thisInnerClass;            for ( ; thisInnerClass < lastInnerClass; thisInnerClass++) {                thisInnerClass->inner_class = get2bytes(context);                thisInnerClass->outer_class = get2bytes(context);                thisInnerClass->inner_name = getAsciz(context, TRUE);                thisInnerClass->access = get2bytes(context);                if (thisInnerClass->inner_class != 0) {                    /* Make sure that inner_class really belongs to a CLASS */                    getAscizFromClass(context, thisInnerClass->inner_class);                }                if (thisInnerClass->outer_class != 0) {                    /* Make sure that outer_class really belongs to a CLASS */                    getAscizFromClass(context, thisInnerClass->outer_class);                }            }        } else {            getNbytes(context, length, NULL);        }    }}/*========================================================================= * FUNCTION:      createFakeArrayClass * OVERVIEW:      Invoked by Locked_FindArrayClassFromClass() for creating *                a fake array class that has the specified fields. * * INTERFACE: *   parameters:  char *: name *                int : base type *                int : depth  (array dimension) *                ClassClass * : base type if T_CLASS *                struct Hjava_lang_ClassLoader *: class loader * *   returns:     ClassClass * *=======================================================================*/ClassClass *createFakeArrayClass(char *name,   /* name */             int base_type,        /* base_type */             int depth,            /* array dimension */             ClassClass *inner_cb, /* base type if T_CLASS */             struct Hjava_lang_ClassLoader *loader){    ClassClass *cb = allocClassClass();    Classjava_lang_Class *ucb = unhand(cb);    cp_item_type *constant_pool =    sysCalloc(CONSTANT_POOL_ARRAY_LENGTH,          (sizeof(cp_item_type) + sizeof(unsigned char)));    unsigned char *type_table = (unsigned char *)        (constant_pool + CONSTANT_POOL_ARRAY_LENGTH);    sysAssert(name[0] == SIGNATURE_ARRAY);    ucb->major_version = JAVA_VERSION;    ucb->minor_version = JAVA_MINOR_VERSION;    ucb->name = strdup(name);    ucb->super_name = JAVAPKG "Object";    ucb->constantpool = constant_pool;    ucb->constantpool_count = CONSTANT_POOL_ARRAY_LENGTH;    ucb->loader = loader;    constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type = type_table;    constant_pool[CONSTANT_POOL_ARRAY_DEPTH_INDEX].i = depth;    constant_pool[CONSTANT_POOL_ARRAY_TYPE_INDEX].i = base_type;    type_table[CONSTANT_POOL_ARRAY_DEPTH_INDEX] =    CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED;    type_table[CONSTANT_POOL_ARRAY_TYPE_INDEX] =    CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED;    if (base_type == T_CLASS) {        /* Initialize the appropriate fields of the constant pool */        constant_pool[CONSTANT_POOL_ARRAY_CLASS_INDEX].clazz = inner_cb;        type_table[CONSTANT_POOL_ARRAY_CLASS_INDEX] =                      CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED;        /* The class is public iff its base class is public */        ucb->access = ACC_FINAL | ACC_ABSTRACT |                      (cbAccess(inner_cb) & ACC_PUBLIC);    } else {        /* Set the class field to something innocuous */        type_table[CONSTANT_POOL_ARRAY_CLASS_INDEX] =                      CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED;        ucb->access = ACC_FINAL | ACC_ABSTRACT | ACC_PUBLIC;    }    AddBinClass(cb);    return cb;}/*========================================================================= * FUNCTION:      createPrimitiveClass * OVERVIEW:      Creates a class block to represent a primitive type. *                NOTE: this is not added to the built-in class table, so *                      it should only be called once per primitive type. *                      See FindPrimitiveClass(). * * INTERFACE: *   parameters:  char *: name *                char  : sig *                unsigned char: typecode *                unsigned char: slotsize *                unsigned char: elementsize * *   returns:     ClassClass * *=======================================================================*/ClassClass *createPrimitiveClass(char *name, char sig, unsigned char typecode,    unsigned char slotsize, unsigned char elementsize){    ClassClass *cb = allocClassClass();    Classjava_lang_Class *ucb = unhand(cb);    ucb->major_version = JAVA_VERSION;    ucb->minor_version = JAVA_MINOR_VERSION;    ucb->name = strdup(name);    ucb->super_name = JAVAPKG "Object";    ucb->constantpool = NULL;    ucb->constantpool_count = 0;    ucb->loader = NULL;    ucb->access = ACC_FINAL | ACC_ABSTRACT | ACC_PUBLIC;    CCSet(cb, Primitive);    cbTypeSig(cb) = sig;    cbTypeCode(cb) = typecode;    cbSlotSize(cb) = slotsize;    cbElementSize(cb) = elementsize;    MakeClassSticky(cb);    return cb;}/*========================================================================= * FUNCTION:      LoadConstantPool * OVERVIEW:      Loads the constant pool given a pointer to the internal *                class file. * * INTERFACE: *   parameters:  CICcontext *: ptr * *   returns:     nothing *=======================================================================*/static void LoadConstantPool(CICcontext *context){    ClassClass *cb = context->cb;    int nconstants = get2bytes(context);    cp_item_type *constant_pool;    unsigned char *type_table;    int i;    Java8 t1;    if (nconstants > 16384) {        JAVA_ERROR(context, "Preverifier only "                   "handles constant pool size up to 16K");    }    t1.x[0] = 0; /* shut off warning */    if (nconstants < CONSTANT_POOL_UNUSED_INDEX) {        JAVA_ERROR(context, "Illegal constant pool size");    }    constant_pool = (cp_item_type *)        allocNBytes(context, nconstants * sizeof(cp_item_type));    type_table = allocNBytes(context, nconstants * sizeof(char));    for (i = CONSTANT_POOL_UNUSED_INDEX; i < nconstants; i++) {        int type = get1byte(context);        CONSTANT_POOL_TYPE_TABLE_PUT(type_table, i, type);        switch (type) {            case CONSTANT_Utf8: {                int length = get2bytes(context);                char *result = allocNBytes(context, length + 1);                getNbytes(context, length, result);                result[length] = '\0';                constant_pool[i].cp = result;                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);                break;            }            case CONSTANT_Class:            case CONSTANT_String:                constant_pool[i].i = get2bytes(context);                break;            case CONSTANT_Fieldref:            case CONSTANT_Methodref:            case CONSTANT_InterfaceMethodref:            case CONSTANT_NameAndType:                constant_pool[i].i = get4bytes(context);                break;            case CONSTANT_Float:                if (no_floating_point) {                    panic("floating-point constants should not appear");                }            case CONSTANT_Integer:                constant_pool[i].i = get4bytes(context);                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);                break;            case CONSTANT_Double:                if (no_floating_point) {                    panic("floating-point constants should not appear");                }            case CONSTANT_Long: {                /* We ignore endian problems, and just load the two                 * values.  The verifier never actually cares what                 * the actual value is.                 */                constant_pool[i].i = get4bytes(context);                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);                i++;                if (i >= nconstants) {                    JAVA_ERROR(context, "illegal constant pool entry");                }                /* Indicate that the next object in the constant pool cannot                 * be accessed independently.                 */                constant_pool[i].i = get4bytes(context);                CONSTANT_POOL_TYPE_TABLE_PUT(type_table, i, 0);                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);                break;            }            default:                JAVA_ERROR(context, "Illegal constant pool type");        }    }    /* It is important to only set these after everything is setup,       so that the GC sees a consistent state.*/    cbConstantPool(cb) = constant_pool;    cbConstantPoolCount(cb) = nconstants;    constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type = type_table;}/*========================================================================= * FUNCTION:      ReadInCode * OVERVIEW:      Reads the code attributes given a pointer to the internal *                class file and a pointer to the method block structure. *                This includes line number and local variable tables. * * INTERFACE: *   parameters:  CICcontext *: ptr *                struct methodblock *: mb * *   returns:     nothing *=======================================================================*/static void ReadInCode(CICcontext *context, struct methodblock *mb){    int attribute_length = get4bytes(context);    unsigned char *end_ptr = context->ptr + attribute_length;    int attribute_count;    int code_length;    int i;    if (cbMinorVersion(context->cb) == JAVA_VERSION &&        cbMinorVersion(context->cb) <= 2) {        mb->maxstack = get1byte(context);        mb->nlocals = get1byte(context);        code_length = mb->code_length = get2bytes(context);    } else {        mb->maxstack = get2bytes(context);        mb->nlocals = get2bytes(context);        code_length = mb->code_length = get4bytes(context);    }    if (mb->nlocals < mb->args_size)        JAVA_ERROR(context, "Arguments can't fit into locals");    if (code_length > 65535) {        JAVA_ERROR(context, "Byte code size exceeds 65535 bytes");    }    mb->code = allocNBytes(context, code_length);    getNbytes(context, code_length, (char *)mb->code);    if ((mb->exception_table_length = get2bytes(context)) > 0) {        unsigned exception_table_size = mb->exception_table_length                                      * sizeof(struct CatchFrame);        mb->exception_table = allocNBytes(context, exception_table_size);        for (i = 0; i < (int)mb->exception_table_length; i++) {            mb->exception_table[i].start_pc = get2bytes(context);            mb->exception_table[i].end_pc = get2bytes(context);            mb->exception_table[i].handler_pc = get2bytes(context);            mb->exception_table[i].catchType = get2bytes(context);            mb->exception_table[i].compiled_CatchFrame = NULL;        }    }    attribute_count = get2bytes(context);    for (i = 0; i < attribute_count; i++) {        char *name = getAsciz(context, FALSE);        if (strcmp(name, "LineNumberTable") == 0) {            ReadLineTable(context, mb);        } else if (strcmp(name, "LocalVariableTable") == 0) {            ReadLocalVars(context, mb);        } else {            int length = get4bytes(context);            getNbytes(context, length, NULL);        }    }    if (context->ptr != end_ptr)        JAVA_ERROR(context, "Code segment was wrong length");}/*========================================================================= * FUNCTION:      ReadLineTable * OVERVIEW:      Reads the line number table given a pointer to the internal *                class file and a pointer to the method block structure. * * INTERFACE: *   parameters:  CICcontext *: ptr *                struct methodblock *: mb * *   returns:     nothing *=======================================================================*/static void ReadLineTable(CICcontext *context, struct methodblock *mb){    int attribute_length = get4bytes(context);    unsigned char *end_ptr = context->ptr  + attribute_length;    int i;    if ((mb->line_number_table_length = get2bytes(context)) > 0) {        struct lineno *ln =               allocNBytes(context, mb->line_number_table_length *                           sizeof(struct lineno));        mb->line_number_table = ln;        for (i = mb->line_number_table_length; --i >= 0; ln++) {            ln->pc = get2bytes(context);            ln->line_number = get2bytes(context);        }    }    if (context->ptr != end_ptr)        JAVA_ERROR(context, "Line number table was wrong length?");}/*========================================================================= * FUNCTION:      ReadLocalVars * OVERVIEW:      Reads the localvar table given a pointer to the internal *                class file and a pointer to the method block structure. * * INTERFACE: *   parameters:  CICcontext *: ptr *                struct methodblock *: mb * *   returns:     nothing *=======================================================================*/static void ReadLocalVars(CICcontext *context, struct methodblock *mb){    int attribute_length = get4bytes(context);    unsigned char *end_ptr = context->ptr  + attribute_length;    int i;    if ((mb->localvar_table_length = get2bytes(context)) > 0) {        struct localvar *lv =               allocNBytes(context, mb->localvar_table_length *                           sizeof(struct localvar));        mb->localvar_table = lv;        for (i = mb->localvar_table_length; --i >= 0; lv++) {            lv->pc0 = get2bytes(context);            lv->length = get2bytes(context);            lv->name = getAsciz(context, FALSE);            lv->signature = getAsciz(context, FALSE);            lv->slot = get2bytes(context);        }    }    if (context->ptr != end_ptr)        JAVA_ERROR(context, "Local variables table was wrong length?");}/*========================================================================= * FUNCTION:      ReadExceptions * OVERVIEW:      Reads the Exception attribute given a pointer to the internal *                class file and a pointer to the method block structure. * * INTERFACE: *   parameters:  CICcontext *: ptr *                struct methodblock *: mb * *   returns:     nothing *=======================================================================*/static voidReadExceptions(CICcontext *context, struct methodblock *mb){    int attribute_length = get4bytes(context);    unsigned char *end_ptr = context->ptr + attribute_length;    unsigned short nexceptions = get2bytes(context);    if ((mb->nexceptions = nexceptions) > 0) {        unsigned short *ep, *exceptions =            allocNBytes(context, nexceptions * sizeof (unsigned short));        mb->exceptions = ep = exceptions;        while (nexceptions-- > 0) {            *ep++ = get2bytes(context);        }    }    if (context->ptr != end_ptr)        JAVA_ERROR(context, "Exceptions attribute has wrong length");}/*========================================================================= * FUNCTION:      Signature2ArgsSize * OVERVIEW:      Returns the size of arguments given a pointer to a method *                signature. * * INTERFACE: *   parameters:  char*: method_signature * *   returns:     unsigned *=======================================================================*/

⌨️ 快捷键说明

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