📄 classloader.c
字号:
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 + -