From fe862dbf491fb9fa09b3581b6151b434835b7e1d Mon Sep 17 00:00:00 2001 From: kgallowa Date: Thu, 15 Feb 2007 15:08:27 +0000 Subject: 2007-02-15 Kyle Galloway * defineclass.cc (_Jv_ClassReader::read_one_code_attribute): Added LocalVariableTable attribute handling. (_Jv_ClassReader::pool_Utf8_to_char_arr): New method. * jvmti.cc (_Jv_JVMTI_GetLocalVariableTable): New method. * include/java-interp.h: Added local_var_table and local_var_table_len fields to _Jv_InterpMethod. (_Jv_InterpMethod::get_local_var_table): New method. * testsuite/libjava.jvmti/interp/getlocalvartable.java: New test. * testsuite/libjava.jvmti/interp/getlocalvartable.jar: New test. * testsuite/libjava.jvmti/interp/getlocalvartable.out: Output for new test. * testsuite/libjava.jvmti/interp/getlocalvartable.h: New test. * testsuite/libjava.jvmti/interp/natgetlocalvartable.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121999 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/defineclass.cc | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'libjava/defineclass.cc') diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc index 12c6032862d..c66fff84b7f 100644 --- a/libjava/defineclass.cc +++ b/libjava/defineclass.cc @@ -299,6 +299,9 @@ struct _Jv_ClassReader /** check an utf8 entry, without creating a Utf8Const object */ bool is_attribute_name (int index, const char *name); + + /** return the value of a utf8 entry in the passed array */ + int pool_Utf8_to_char_arr (int index, char **entry); /** here goes the class-loader members defined out-of-line */ void handleConstantPool (); @@ -784,6 +787,18 @@ _Jv_ClassReader::is_attribute_name (int index, const char *name) return !memcmp (bytes+offsets[index]+2, name, len); } +// Get a UTF8 value from the constant pool and turn it into a garbage +// collected char array. +int _Jv_ClassReader::pool_Utf8_to_char_arr (int index, char** entry) +{ + check_tag (index, JV_CONSTANT_Utf8); + int len = get2u (bytes + offsets[index]); + *entry = reinterpret_cast (_Jv_AllocBytes (len + 1)); + (*entry)[len] = '\0'; + memcpy (*entry, bytes + offsets[index] + 2, len); + return len + 1; +} + void _Jv_ClassReader::read_one_field_attribute (int field_index, bool *found_value) { @@ -979,6 +994,34 @@ void _Jv_ClassReader::read_one_code_attribute (int method_index) method->line_table_len = table_len; method->line_table = table; } + else if (is_attribute_name (name, "LocalVariableTable")) + { + _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *> + (def_interp->interpreted_methods[method_index]); + if (method->local_var_table != NULL) + throw_class_format_error ("Method already has LocalVariableTable"); + + int table_len = read2u (); + _Jv_LocalVarTableEntry *table + = reinterpret_cast<_Jv_LocalVarTableEntry *> + (_Jv_AllocRawObj (table_len * sizeof (_Jv_LocalVarTableEntry))); + + for (int i = 0; i < table_len; i++) + { + table[i].bytecode_start_pc = read2u (); + table[i].length = read2u (); + int len; + len = pool_Utf8_to_char_arr (read2u (), &table[i].name); + len = pool_Utf8_to_char_arr (read2u (), &table[i].descriptor); + table[i].slot = read2u (); + + if (table[i].slot > method->max_locals || table[i].slot < 0) + throw_class_format_error ("Malformed Local Variable Table: Invalid Slot"); + } + + method->local_var_table_len = table_len; + method->local_var_table = table; + } else { /* ignore unknown code attributes */ -- cgit v1.2.3