diff --git a/c/class_file.c b/c/class_file.c index 6f6eee0..8a72855 100644 --- a/c/class_file.c +++ b/c/class_file.c @@ -90,6 +90,15 @@ void * attribute_info_parse_info(const uint8_t * buf, struct attribute_info * at line_number_table->line_number_table[i].line_number = parse_u2(&buf); } return line_number_table; + } else if (constant_equal(attribute_name, "Exceptions")) { + struct Exceptions_attribute * exceptions = malloc_class_arena((sizeof (struct Exceptions_attribute))); + exceptions->number_of_exceptions = parse_u2(&buf); + uint32_t exceptions_size = (sizeof (u2)) * exceptions->number_of_exceptions; + exceptions->exception_index_table = malloc_class_arena(exceptions_size); + for (int i = 0; i < exceptions->number_of_exceptions; i++) { + exceptions->exception_index_table[i] = parse_u2(&buf); + } + return exceptions; } else { return nullptr; } diff --git a/c/class_file.h b/c/class_file.h index 1868c79..6758247 100644 --- a/c/class_file.h +++ b/c/class_file.h @@ -136,6 +136,7 @@ struct NestHost_attribute; struct NestMembers_attribute; struct PermittedSubclasses_attribute; struct LineNumberTable_attribute; +struct Exceptions_attribute; struct attribute_info { u2 attribute_name_index; @@ -150,6 +151,7 @@ struct attribute_info { struct NestMembers_attribute * nestmembers; //struct PermittedSubclasses_attribute * permittedsubclasses; struct LineNumberTable_attribute * line_number_table; + struct Exceptions_attribute * exceptions; }; }; @@ -205,6 +207,11 @@ struct LineNumberTable_attribute { struct line_number_table * line_number_table; }; +struct Exceptions_attribute { + u2 number_of_exceptions; + u2 * exception_index_table; +}; + enum FIELD_ACC { FIELD_ACC_PUBLIC = 0x0001, // Declared public; may be accessed from outside its package. FIELD_ACC_PRIVATE = 0x0002, // Declared private; accessible only within the defining class and other classes belonging to the same nest (ยง5.4.4). diff --git a/c/debug_class_file.c b/c/debug_class_file.c index 9e1860d..6db322a 100644 --- a/c/debug_class_file.c +++ b/c/debug_class_file.c @@ -224,6 +224,28 @@ static void print_line_number_table(const char * indent, struct attribute_info * } } +static void print_exceptions(const char * indent, struct attribute_info * attribute, struct constant * constant_pool) +{ + prints(indent); + printf("number_of_exceptions: %d\n", attribute->exceptions->number_of_exceptions); + prints(indent); + printf("exceptions:\n"); + for (int i = 0; i < attribute->exceptions->number_of_exceptions; i++) { + prints(indent); + printf(" exception_index_table[%d]: %d\n", i, attribute->exceptions->exception_index_table[i]); + struct constant * class_constant = &constant_pool[attribute->exceptions->exception_index_table[i] - 1]; + assert(class_constant->tag == CONSTANT_Class); + prints(indent); + prints(" "); + print_constant(class_constant); + struct constant * class_name_constant = &constant_pool[class_constant->class.name_index - 1]; + assert(class_name_constant->tag == CONSTANT_Utf8); + prints(indent); + prints(" "); + print_constant(class_name_constant); + } +} + static void print_attribute(const char * indent, struct attribute_info * attribute, struct constant * constant_pool) { prints(indent); @@ -245,6 +267,8 @@ static void print_attribute(const char * indent, struct attribute_info * attribu print_nestmembers(indent, attribute, constant_pool); } else if (constant_equal(attribute_name, "LineNumberTable")) { print_line_number_table(indent, attribute, constant_pool); + } else if (constant_equal(attribute_name, "Exceptions")) { + print_exceptions(indent, attribute, constant_pool); } } diff --git a/java/lang/Throwable.java b/java/lang/Throwable.java index 1d9398e..2eb6c35 100644 --- a/java/lang/Throwable.java +++ b/java/lang/Throwable.java @@ -20,4 +20,8 @@ public class Throwable { public Throwable(Throwable cause) { this.cause = cause; } + + public String toString() { + return message; + } } diff --git a/p/TestException.java b/p/TestException.java index 90d094b..bf9273a 100644 --- a/p/TestException.java +++ b/p/TestException.java @@ -1,8 +1,16 @@ package p; class TestException { + static void test2() throws Exception { + throw new Exception("asdf exception"); + } + static void test() throws Exception { - throw new Exception("asdf"); + try { + test2(); + } catch (Exception e) { + System.out.println(e); + } } public static void main() throws Exception {