OSDN Git Service

2007-02-15 Kyle Galloway <kgallowa@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / defineclass.cc
index 12c6032..c66fff8 100644 (file)
@@ -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 */