readclass.c
来自「基于LWVCL开发的库」· C语言 代码 · 共 470 行
C
470 行
/* * 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 NULL; /* Read in class info */ readu4(&magic, fp); if (magic != JAVAMAGIC) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "Bad magic number 0x%x", magic); return NULL; } 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) || (major_version == MAJOR_VERSION_V1_5 && minor_version == MINOR_VERSION_V1_5) || (major_version == MAJOR_VERSION_V1_6 && minor_version == MINOR_VERSION_V1_6))) { postExceptionMessage(einfo, JAVA_LANG(UnsupportedClassVersionError), "%d.%d", major_version, minor_version); return NULL; } if (readConstantPool(classThis, fp, einfo) == false) { return NULL; } if (! checkBufSize(fp, 2+2+2, className, einfo)) return NULL; readu2(&access_flags, fp); readu2(&this_class, fp); readu2(&super_class, fp); if (! setupClass(classThis, this_class, super_class, access_flags, loader, einfo)) { return (NULL); } /* 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 NULL; } 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, (u2)(interfaces_count * 2), CLASS_CNAME(this), einfo)) return false; interfaces = (Hjava_lang_Class**) gc_malloc(sizeof(Hjava_lang_Class**) * interfaces_count, KGC_ALLOC_INTERFACE); if (interfaces == NULL) { 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; } if (!gc_add_ref(interfaces)) { postOutOfMemory(einfo); return false; } 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);}#if !defined(KAFFEH)static boolreadSignatureAttribute(Hjava_lang_Class* this, u2 idx, Utf8Const **signature, errorInfo *einfo){ constants* pool; pool = CLASS_CONSTANTS (this); if (idx >= CLASS_CONST_SIZE (this) || pool->tags[idx] != CONSTANT_Utf8) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "invalid signature index: %d", idx); return false; } *signature = WORD2UTF (pool->data[idx]); return true;}static boolreadEnclosingMethodAttribute(classFile *fp, u4 len, Hjava_lang_Class* this, errorInfo *einfo){ u2 class_index, method_index; if (len != 4) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "invalid attribute size for %s", CLASS_CNAME(this)); return false; } readu2(&class_index, fp); readu2(&method_index, fp); if (class_index >= CLASS_CONST_SIZE(this) || method_index >= CLASS_CONST_SIZE(this)) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "invalid constant index for %s", CLASS_CNAME(this)); return false; } this->enclosingClassIndex = class_index; this->enclosingMethodIndex = method_index; return true;}#endif /* !defined(KAFFEH) *//* * 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, (size_t) len, fp, einfo)) { DBG(READCLASS, dprintf("%s: error parsing code\n", CLASS_CNAME(this)); ); return false; } } else if (utf8ConstEqual(name, LineNumberTable_name) && (thingType == READATTR_METHOD)) { if (!addLineNumbers((Method*)thing, (size_t) len, fp, einfo)) { DBG(READCLASS, dprintf("%s: error parsing line number table\n", CLASS_CNAME(this)); ); return false; } } else if (utf8ConstEqual(name, LocalVariableTable_name) && (thingType == READATTR_METHOD)) { if (!addLocalVariables((Method*)thing, (size_t) len, fp, einfo)) { DBG(READCLASS, dprintf("%s: error parsing local variable table\n", CLASS_CNAME(this)); ); 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, (size_t) 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, (size_t) len, fp, einfo)) { return false; } }#if !defined(KAFFEH) else if (utf8ConstEqual(name, EnclosingMethod_name) && thingType == READATTR_CLASS) { if (!readEnclosingMethodAttribute(fp, len, (struct Hjava_lang_Class*)thing, einfo)) return false; } else if (utf8ConstEqual(name, Synthetic_name)) { switch (thingType) { case READATTR_CLASS: ((Hjava_lang_Class *)thing)->accflags |= ACC_SYNTHETIC; break; case READATTR_METHOD: ((Method *)thing)->accflags |= ACC_SYNTHETIC; break; case READATTR_FIELD: ((Field *)thing)->accflags |= ACC_SYNTHETIC; break; } } else if (utf8ConstEqual(name, Signature_name)) { Utf8Const *signature; readu2(&idx, fp); if (!readSignatureAttribute(this, idx, &signature, einfo)) return false; switch (thingType) { case READATTR_CLASS: ((Hjava_lang_Class *)thing)->extSignature = signature; break; case READATTR_METHOD: ((Method *)thing)->extSignature = signature; break; case READATTR_FIELD: ((Field *)thing)->extSignature = signature; break; } }#endif 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 + -
显示快捷键?