// defineclass.cc - defining a class from .class format.
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation
This file is part of libgcj.
/** 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 ();
#define MINOR_1_4 0
#define MAJOR_1_5 49
#define MINOR_1_5 0
+#define MAJOR_1_6 50
+#define MINOR_1_6 0
+#define MAJOR_1_7 51
+#define MINOR_1_7 0
void
_Jv_ClassReader::parse ()
int minor_version = read2u ();
int major_version = read2u ();
- if (major_version < MAJOR_1_1 || major_version > MAJOR_1_5
- || (major_version == MAJOR_1_5 && minor_version > MINOR_1_5))
+ if (major_version < MAJOR_1_1 || major_version > MAJOR_1_7
+ || (major_version == MAJOR_1_7 && minor_version > MINOR_1_7))
throw_class_format_error ("unrecognized class file version");
- is_15 = (major_version == MAJOR_1_5);
+ is_15 = (major_version >= MAJOR_1_5);
pool_count = read2u ();
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)
{
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_pc = read2u ();
+ table[i].length = read2u ();
+ pool_Utf8_to_char_arr (read2u (), &table[i].name);
+ 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 */
method->prepared = NULL;
method->line_table_len = 0;
method->line_table = NULL;
-
+#ifdef DIRECT_THREADED
+ method->thread_count = 0;
+#endif
// grab the byte code!
memcpy ((void*) method->bytecode (),
// call a static method of an interpreted class from precompiled
// code without first resolving the class (that will happen
// during class initialization instead).
- method->self->ncode = method->ncode ();
+ method->self->ncode = method->ncode (def);
}
}
// interpreted class from precompiled code without
// first resolving the class (that will happen
// during class initialization instead).
- method->ncode = m->ncode ();
+ method->ncode = m->ncode (def);
}
}
}