summaryrefslogtreecommitdiff
path: root/libjava/defineclass.cc
diff options
context:
space:
mode:
authorkgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-15 15:08:27 +0000
committerkgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-15 15:08:27 +0000
commitfe862dbf491fb9fa09b3581b6151b434835b7e1d (patch)
treed582917d66a2280e29d258af271b3d5500823c60 /libjava/defineclass.cc
parent35c2394dee3a6c7094cfc7d3fecb7dd0bddac894 (diff)
downloadgcc-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.cc43
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 */