// defineclass.cc - defining a class from .class format.
-/* Copyright (C) 1999, 2000 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation
This file is part of libgcj.
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/reflect/Modifier.h>
-// we don't verify method names that match these.
-static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
+using namespace gcj;
-
-// these go in some seperate functions, to avoid having _Jv_InitClass
+// these go in some separate functions, to avoid having _Jv_InitClass
// inserted all over the place.
static void throw_internal_error (char *msg)
__attribute__ ((__noreturn__));
void _Jv_ClassReader::read_constpool ()
{
- tags = (unsigned char*) _Jv_AllocBytesChecked (pool_count);
- offsets = (unsigned int *) _Jv_AllocBytesChecked (sizeof (int)
+ tags = (unsigned char*) _Jv_AllocBytes (pool_count);
+ offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
* pool_count) ;
/** first, we scan the constant pool, collecting tags and offsets */
if (is_attribute_name (name, "Exceptions"))
{
- /* we ignore this for now */
- skip (length);
+ _Jv_Method *method = reinterpret_cast<_Jv_Method *>
+ (&def->methods[method_index]);
+ if (method->throws != NULL)
+ throw_class_format_error ("only one Exceptions attribute allowed per method");
+
+ int num_exceptions = read2u ();
+ // We use malloc here because the GC won't scan the method
+ // objects. FIXME this means a memory leak if we GC a class.
+ // (Currently we never do.)
+ _Jv_Utf8Const **exceptions =
+ (_Jv_Utf8Const **) _Jv_Malloc ((num_exceptions + 1) * sizeof (_Jv_Utf8Const *));
+
+ int out = 0;
+ _Jv_word *pool_data = def->constants.data;
+ for (int i = 0; i < num_exceptions; ++i)
+ {
+ try
+ {
+ int ndx = read2u ();
+ // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
+ if (ndx != 0)
+ {
+ check_tag (ndx, JV_CONSTANT_Class);
+ exceptions[out++] = pool_data[ndx].utf8;
+ }
+ }
+ catch (java::lang::Throwable *exc)
+ {
+ _Jv_Free (exceptions);
+ throw exc;
+ }
+ }
+ exceptions[out] = NULL;
+ method->throws = exceptions;
}
-
+
else if (is_attribute_name (name, "Code"))
{
int start_off = pos;
/** now, we actually define the class' constant pool */
// the pool is scanned explicitly by the collector
- jbyte *pool_tags = (jbyte*) _Jv_AllocBytesChecked (pool_count);
+ jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
_Jv_word *pool_data
- = (_Jv_word*) _Jv_AllocBytesChecked (pool_count * sizeof (_Jv_word));
+ = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
def->constants.tags = pool_tags;
def->constants.data = pool_data;
// to include references to this class.
def->state = JV_STATE_PRELOADING;
- _Jv_RegisterClass (def);
+
+ {
+ JvSynchronize sync (&java::lang::Class::class$);
+ _Jv_RegisterClass (def);
+ }
if (super_class != 0)
{
void _Jv_ClassReader::handleInterfacesBegin (int count)
{
- def->interfaces = (jclass*) _Jv_AllocBytesChecked (count*sizeof (jclass));
+ def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
def->interface_count = count;
}
void _Jv_ClassReader::handleFieldsBegin (int count)
{
def->fields = (_Jv_Field*)
- _Jv_AllocBytesChecked (count * sizeof (_Jv_Field));
+ _Jv_AllocBytes (count * sizeof (_Jv_Field));
def->field_count = count;
def->field_initializers = (_Jv_ushort*)
- _Jv_AllocBytesChecked (count * sizeof (_Jv_ushort));
+ _Jv_AllocBytes (count * sizeof (_Jv_ushort));
for (int i = 0; i < count; i++)
def->field_initializers[i] = (_Jv_ushort) 0;
}
_Jv_ClassReader::handleMethodsBegin (int count)
{
def->methods = (_Jv_Method*)
- _Jv_AllocBytesChecked (sizeof (_Jv_Method)*count);
+ _Jv_AllocBytes (sizeof (_Jv_Method)*count);
def->interpreted_methods
- = (_Jv_MethodBase **) _Jv_AllocBytesChecked (sizeof (_Jv_MethodBase *)
- * count);
+ = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
+ * count);
for (int i = 0; i < count; i++)
def->interpreted_methods[i] = 0;
// intialize...
method->ncode = 0;
+ method->throws = NULL;
if (verify)
{
{
int size = _Jv_InterpMethod::size (exc_table_length, code_length);
_Jv_InterpMethod *method =
- (_Jv_InterpMethod*) (_Jv_AllocBytesChecked (size));
+ (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
method->max_stack = max_stack;
method->max_locals = max_locals;
else
{
_Jv_JNIMethod *m = (_Jv_JNIMethod *)
- _Jv_AllocBytesChecked (sizeof (_Jv_JNIMethod));
+ _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
m->defining_class = def;
m->self = method;
m->function = NULL;
static void
throw_no_class_def_found_error (jstring msg)
{
- if (msg == 0)
- JvThrow (new java::lang::NoClassDefFoundError);
- else
- JvThrow (new java::lang::NoClassDefFoundError (msg));
+ throw (msg
+ ? new java::lang::NoClassDefFoundError (msg)
+ : new java::lang::NoClassDefFoundError);
}
static void
static void
throw_class_format_error (jstring msg)
{
- if (msg == 0)
- JvThrow (new java::lang::ClassFormatError);
- else
- JvThrow (new java::lang::ClassFormatError (msg));
+ throw (msg
+ ? new java::lang::ClassFormatError (msg)
+ : new java::lang::ClassFormatError);
}
static void
throw_internal_error (char *msg)
{
- JvThrow
- (new java::lang::InternalError (JvNewStringLatin1 (msg)));
+ throw new java::lang::InternalError (JvNewStringLatin1 (msg));
}
static jfloat int_bits_to_float (jint value)
static void throw_incompatible_class_change_error (jstring msg)
{
- JvThrow (new java::lang::IncompatibleClassChangeError (msg));
+ throw new java::lang::IncompatibleClassChangeError (msg);
}
static void throw_class_circularity_error (jstring msg)
{
- JvThrow (new java::lang::ClassCircularityError (msg));
+ throw new java::lang::ClassCircularityError (msg);
}
#endif /* INTERPRETER */