diff options
author | kgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-15 15:08:27 +0000 |
---|---|---|
committer | kgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-15 15:08:27 +0000 |
commit | fe862dbf491fb9fa09b3581b6151b434835b7e1d (patch) | |
tree | d582917d66a2280e29d258af271b3d5500823c60 /libjava/defineclass.cc | |
parent | 35c2394dee3a6c7094cfc7d3fecb7dd0bddac894 (diff) | |
download | gcc-fe862dbf491fb9fa09b3581b6151b434835b7e1d.tar.gz |
2007-02-15 Kyle Galloway <kgallowa@redhat.com>
* 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
Diffstat (limited to 'libjava/defineclass.cc')
-rw-r--r-- | libjava/defineclass.cc | 43 |
1 files changed, 43 insertions, 0 deletions
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<char *> (_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 */ |