📄 code.c
字号:
/* * code.c * Process a new code attribute. * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * Copyright (c) 2004 * Kaffe.org contributors. See ChangeLog for details. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "debug.h"#include "config.h"#include "config-std.h"#include "config-mem.h"#include "jni_md.h"#include "file.h"#include "errors.h"#include "bytecode.h"#include "code.h"#include "access.h"#include "object.h"#include "classMethod.h"#include "readClass.h"#include "exception.h"booladdCode(Method* m, size_t len UNUSED, classFile* fp, errorInfo *einfo){ bool retval = false; Code c; int i; u2 i2; u2 elen; /* no checkBufSize calls necessary, done in caller (readAttributes) */ readu2(&c.max_stack, fp); readu2(&c.max_locals, fp); readu4(&c.code_length, fp); DBG(CODEATTR, dprintf("addCode for method %s.%s\n", CLASS_CNAME(m->class), m->name->data); dprintf("Max stack = %d\n", c.max_stack); dprintf("Max locals = %d\n", c.max_locals); dprintf("Code length = %d\n", c.code_length); ); if ((c.code_length > 0) && (c.code_length < 65536)) { c.code = gc_malloc(c.code_length, KGC_ALLOC_BYTECODE); if (c.code == 0) { postOutOfMemory(einfo); return (false); } DBG(CODEATTR, dprintf("allocating bytecode @%p\n", c.code); ); readm(c.code, c.code_length, sizeof(bytecode), fp); readu2(&elen, fp); DBG(CODEATTR, dprintf("Exception table length = %d\n", elen); ); if (elen > 0) { c.exception_table = gc_malloc(sizeof(jexception) + ((elen - 1) * sizeof(jexceptionEntry)), KGC_ALLOC_EXCEPTIONTABLE); if (c.exception_table == 0) { if (c.code) { gc_free(c.code); } return false; } c.exception_table->length = elen; for (i = 0; i < elen; i++) { readu2(&i2, fp); c.exception_table->entry[i].start_pc = i2; readu2(&i2, fp); c.exception_table->entry[i].end_pc = i2; readu2(&i2, fp); c.exception_table->entry[i].handler_pc = i2; readu2(&i2, fp); c.exception_table->entry[i].catch_idx = i2; c.exception_table->entry[i].catch_type = NULL; } } else { c.exception_table = NULL; } KGC_WRITE(m, c.code); KGC_WRITE(m, c.exception_table); addMethodCode(m, &c); retval = readAttributes(fp, m->class, READATTR_METHOD, m, einfo); } else if (c.code_length == 0) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "(class: %s, method: %s signature: %s) " "Code of a method has length 0", m->class->name->data, m->name->data, Kaffe_get_class_methods(m->class) [m - Kaffe_get_class_methods(m->class)]. parsed_sig->signature->data); } else { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "(class: %s, method: %s signature: %s) " "Code of a method longer than 65535 bytes", m->class->name->data, m->name->data, Kaffe_get_class_methods(m->class) [m - Kaffe_get_class_methods(m->class)]. parsed_sig->signature->data); } return (retval);}/* * Read in line numbers assocated with code. */booladdLineNumbers(Method* m, size_t len UNUSED, classFile* fp, errorInfo *info){ lineNumbers* lines; int i; u2 nr; u2 data; /* no checkBufSize, done in caller (readAttributes) */ readu2(&nr, fp); lines = gc_malloc(sizeof(lineNumbers)+sizeof(lineNumberEntry) * nr, KGC_ALLOC_LINENRTABLE); if (!lines) { DBG(READCLASS, dprintf("%s (%s): failed to allocate %lu bytes for %d line number table entries.\n", CLASS_CNAME(m->class), m->name->data, (unsigned long) sizeof(lineNumbers)+sizeof(lineNumberEntry) * nr, nr); ); postOutOfMemory(info); return false; } lines->length = nr; for (i = 0; i < nr; i++) { readu2(&data, fp); lines->entry[i].start_pc = data; readu2(&data, fp); lines->entry[i].line_nr = data; if (lines->entry[i].start_pc > m->c.bcode.codelen) { DBG(READCLASS, dprintf("%s (%s): start pc %lu of line number entry %d > method length %d.\n", CLASS_CNAME(m->class), m->name->data, (unsigned long) lines->entry[i].start_pc, i, m->c.bcode.codelen); ); postExceptionMessage(info, JAVA_LANG(ClassFormatError), "%s " "(Method \"%s\" has invalid pc, " "%ld, for line number %d)", CLASS_CNAME(m->class), m->name->data, (long)lines->entry[i].start_pc, lines->entry[i].line_nr); return false; } } /* Attach lines to method */ m->lines = lines; return true;}booladdLocalVariables(Method *m, size_t len UNUSED, classFile *fp, errorInfo *info){ constants *pool = CLASS_CONSTANTS(m->class); localVariables *lv; int i; u2 nr; u2 data; readu2(&nr, fp); lv = gc_malloc(sizeof(localVariables) + (sizeof(localVariableEntry) * nr), KGC_ALLOC_LOCALVARTABLE); if( lv == NULL ) { postOutOfMemory(info); return false; } lv->length = nr; for( i = 0; i < nr; i++ ) { readu2(&data, fp); lv->entry[i].start_pc = data; readu2(&data, fp); lv->entry[i].length = data; readu2(&data, fp); lv->entry[i].name_index = data; readu2(&data, fp); lv->entry[i].descriptor_index = data; readu2(&data, fp); lv->entry[i].index = data; if (pool->tags[lv->entry[i].name_index] != CONSTANT_Utf8) { postExceptionMessage(info, JAVA_LANG(ClassFormatError), "invalid local variable " "name_index: %d", lv->entry[i].name_index); return false; } if (pool->tags[lv->entry[i].descriptor_index] != CONSTANT_Utf8) { postExceptionMessage(info, JAVA_LANG(ClassFormatError), "invalid local variable " "descriptor_index: %d", lv->entry[i].name_index); return false; } if (lv->entry[i].index > m->localsz) { postExceptionMessage(info, JAVA_LANG(ClassFormatError), "invalid local variable " "index: %d", lv->entry[i].index); return false; } } m->lvars = lv; return true;}/* * Read in (checked) exceptions declared for a method */booladdCheckedExceptions(Method* m, size_t len UNUSED, classFile* fp, errorInfo *info){ int i; u2 nr; constIndex *idx; /* no checkBufSize, done in caller (readAttributes) */ readu2(&nr, fp); if (nr == 0) { return true; } m->ndeclared_exceptions = nr; idx = gc_malloc(sizeof(constIndex) * nr, KGC_ALLOC_DECLAREDEXC); if (!idx) { postOutOfMemory(info); return false; } m->declared_exceptions = idx; for (i = 0; i < nr; i++) { readu2(idx + i, fp); } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -