readclass.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 351 行
C
351 行
/* * readClass.c * Read in a new class. * * Copyright (c) 1996, 1997, 1998, 1999 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "config-std.h"#include "config-io.h"#include "config-mem.h"#include "debug.h"#include "gtypes.h"#include "file.h"#include "access.h"#include "object.h"#include "constants.h"#include "errors.h"#include "debug.h"#include "readClass.h"#include "classMethod.h"#include "code.h"#include "utf8const.h"Hjava_lang_Class*readClass(Hjava_lang_Class* classThis, classFile* fp, struct Hjava_lang_ClassLoader* loader, errorInfo *einfo){ u2 minor_version; u2 major_version; u4 magic; u2 access_flags; u2 this_class; u2 super_class; /* CLASS_CNAME(classThis) won't work until after 'setupClass', below */ const char* className = NULL; if (! checkBufSize(fp, 4+2+2, className, einfo)) return 0; /* Read in class info */ readu4(&magic, fp); if (magic != JAVAMAGIC) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "Bad magic number 0x%x", magic); return 0; } readu2(&minor_version, fp); readu2(&major_version, fp); /* Note, can't print CLASS_CNAME(classThis), as name isn't initialized yet... */ DBG(READCLASS, dprintf("major=%d, minor=%d\n", major_version, minor_version); ); if (! ((major_version == MAJOR_VERSION_V1_1 && minor_version == MINOR_VERSION_V1_1) || (major_version == MAJOR_VERSION_V1_2 && minor_version == MINOR_VERSION_V1_2) || (major_version == MAJOR_VERSION_V1_3 && minor_version == MINOR_VERSION_V1_3) || (major_version == MAJOR_VERSION_V1_4 && minor_version == MINOR_VERSION_V1_4))) { postExceptionMessage(einfo, JAVA_LANG(UnsupportedClassVersionError), "%d.%d", major_version, minor_version); } if (readConstantPool(classThis, fp, einfo) == false) { return 0; } if (! checkBufSize(fp, 2+2+2, className, einfo)) return 0; readu2(&access_flags, fp); readu2(&this_class, fp); readu2(&super_class, fp); if (! setupClass(classThis, this_class, super_class, access_flags, loader, einfo)) { return (0); } /* CLASS_CNAME(classThis) is now defined. */ if (readInterfaces(fp, classThis, einfo) == false || readFields(fp, classThis, einfo) == false || readMethods(fp, classThis, einfo) == false || readAttributes(fp, classThis, READATTR_CLASS, classThis, einfo) == false) { return 0; } return (classThis);}/* * Read in interfaces. */boolreadInterfaces(classFile* fp, Hjava_lang_Class* this, errorInfo *einfo){ Hjava_lang_Class** interfaces; u2 interfaces_count; u2 i; if (! checkBufSize(fp, 2, CLASS_CNAME(this), einfo)) return false; readu2(&interfaces_count, fp); DBG(READCLASS, dprintf("%s: interfaces_count=%d\n", CLASS_CNAME(this), interfaces_count); ); if (interfaces_count == 0) { return true; } if (! checkBufSize(fp, interfaces_count * 2, CLASS_CNAME(this), einfo)) return false; interfaces = (Hjava_lang_Class**) gc_malloc(sizeof(Hjava_lang_Class**) * interfaces_count, GC_ALLOC_INTERFACE); if (interfaces == 0) { postOutOfMemory(einfo); return false; } for (i = 0; i < interfaces_count; i++) { u2 iface; readu2(&iface, fp); /* Will be converted from idx to Class* in processClass() */ interfaces[i] = (Hjava_lang_Class*) (size_t) iface; } addInterfaces(this, interfaces_count, interfaces); return true;}/* * Read in fields. */boolreadFields(classFile* fp, Hjava_lang_Class* this, errorInfo *einfo){ u2 i; u2 fields_count; if (! checkBufSize(fp, 2, CLASS_CNAME(this), einfo)) return false; readu2(&fields_count, fp); DBG(READCLASS, dprintf("%s: fields_count=%d\n", CLASS_CNAME(this), fields_count); ); if( !startFields(this, fields_count, einfo) ) return false; for (i = 0; i < fields_count; i++) { Field* fieldThis; u2 access_flags; u2 name_index; u2 signature_index; if (! checkBufSize(fp, 2+2+2, CLASS_CNAME(this), einfo)) return false; readu2(&access_flags, fp); readu2(&name_index, fp); readu2(&signature_index, fp); fieldThis = addField(this, access_flags, name_index, signature_index, einfo); if (fieldThis == NULL) return false; if (! readAttributes(fp, this, READATTR_FIELD, fieldThis, einfo)) return false; } finishFields(this); return (true);}/* * Read in attributes. */boolreadAttributes(classFile* fp, Hjava_lang_Class* this, ReadAttrType thingType, void* thing, errorInfo *einfo){ u2 i; u2 cnt; if (! checkBufSize(fp, 2, CLASS_CNAME(this), einfo)) return false; readu2(&cnt, fp); DBG(READCLASS, dprintf("%s: attributes_count=%d\n", CLASS_CNAME(this), cnt); ); for (i = 0; i < cnt; i++) { u2 idx; u4 len; if (! checkBufSize(fp, 2+4, CLASS_CNAME(this), einfo)) return false; readu2(&idx, fp); readu4(&len, fp); if (! checkBufSize(fp, len, CLASS_CNAME(this), einfo)) return false; if (CLASS_CONST_TAG(this, idx) == CONSTANT_Utf8) { Utf8Const* name; name = WORD2UTF(CLASS_CONST_DATA (this, idx)); DBG(READCLASS, dprintf("%s: parsing attr %s on %s\n", CLASS_CNAME(this), name->data, (thingType == READATTR_METHOD) ? "Method" : ((thingType == READATTR_CLASS) ? "Class" : ((thingType == READATTR_FIELD) ? "Field" : "unknown enum element"))); ); if (utf8ConstEqual(name, Code_name) && (thingType == READATTR_METHOD)) { if (! addCode((Method*)thing, len, fp, einfo)) { return false; } } else if (utf8ConstEqual(name, LineNumberTable_name) && (thingType == READATTR_METHOD)) { if (!addLineNumbers((Method*)thing, len, fp, einfo)) { return false; } } else if (utf8ConstEqual(name, ConstantValue_name) && (thingType == READATTR_FIELD)) { readu2(&idx, fp); setFieldValue(this, (Field*)thing, idx); } else if (utf8ConstEqual(name, Exceptions_name) && (thingType == READATTR_METHOD)) { if (!addCheckedExceptions((Method*)thing, len, fp, einfo)) { return false; } } else if (utf8ConstEqual(name, SourceFile_name) && (thingType == READATTR_CLASS)) { readu2(&idx, fp); if (! addSourceFile((Hjava_lang_Class*)thing, idx, einfo)) { return false; } } else if (utf8ConstEqual(name, InnerClasses_name) && (thingType == READATTR_CLASS)) { if(! addInnerClasses((Hjava_lang_Class*)thing, len, fp, einfo)) { return false; } } else { DBG(READCLASS, dprintf("%s: don't know how to parse %s on %s\n", CLASS_CNAME(this), name->data, (thingType == READATTR_METHOD) ? "Method" : ((thingType == READATTR_CLASS) ? "Class" : ((thingType == READATTR_FIELD) ? "Field" : "unknown enum element"))); ); seekm(fp, len); } } else { /* XXX should this throw an exception? */ DBG(READCLASS, dprintf("%s: WARNING! Skipping broken(?) attribute (name is not a Utf8 constant).\n", CLASS_CNAME(this))); seekm(fp, len); } } return true;}/* * Read in methods. */boolreadMethods(classFile* fp, Hjava_lang_Class* this, errorInfo *einfo){ u2 i; u2 methods_count; if (! checkBufSize(fp, 2, CLASS_CNAME(this), einfo)) return false; readu2(&methods_count, fp); DBG(READCLASS, dprintf("%s: methods_count=%d\n", CLASS_CNAME(this), methods_count); ); if( !startMethods(this, methods_count, einfo) ) return false; for (i = 0; i < methods_count; i++) { Method* methodThis; u2 access_flags; u2 name_index; u2 signature_index; if (! checkBufSize(fp, 2+2+2, CLASS_CNAME(this), einfo)) return false; readu2(&access_flags, fp); readu2(&name_index, fp); readu2(&signature_index, fp); methodThis = addMethod(this, access_flags, name_index, signature_index, einfo); if (methodThis == NULL) { return false; } if (readAttributes(fp, this, READATTR_METHOD, methodThis, einfo) == false) { return false; } }#ifdef KAFFEH finishMethods(this);#endif return (true);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?