// defineclass.cc - defining a class from .class format.
-/* Copyright (C) 1999 Cygnus Solutions
+/* Copyright (C) 1999, 2000 Red Hat, Inc.
This file is part of libgcj.
currently being ignored ("InnerClasses", "LineNumber", etc...).
*/
+#include <config.h>
+
#include <java-interp.h>
#ifdef INTERPRETER
#include <java-cpool.h>
-#include <cni.h>
+#include <gcj/cni.h>
#include <java/lang/Class.h>
#include <java/lang/Float.h>
#include <java/lang/ClassCircularityError.h>
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/reflect/Modifier.h>
#define ClassClass _CL_Q34java4lang5Class
extern java::lang::Class ClassClass;
-#define StringClass _CL_Q34java4lang6String
-extern java::lang::Class StringClass;
#define ClassObject _CL_Q34java4lang6Object
extern java::lang::Class ClassObject;
* could be implemented in prims.cc (_Jv_makeUtf8Const), since it
* computes the hash value anyway.
*/
-
- static const int PUBLIC = 0x001;
- static const int PRIVATE = 0x002;
- static const int PROTECTED = 0x004;
- static const int STATIC = 0x008;
- static const int FINAL = 0x010;
- static const int SYNCHRONIZED = 0x020;
- static const int VOLATILE = 0x040;
- static const int TRANSIENT = 0x080;
- static const int NATIVE = 0x100;
- static const int INTERFACE = 0x200;
- static const int ABSTRACT = 0x400;
- static const int ALL_FLAGS = 0x7FF;
-
};
/* This is used for the isJavaIdentifierStart & isJavaIdentifierPart
// the pool is scanned explicitly by the collector
jbyte *pool_tags = (jbyte*) _Jv_AllocBytesChecked (pool_count);
- void **pool_data = (void**) _Jv_AllocBytesChecked (pool_count * sizeof (void*));
+ _Jv_word *pool_data
+ = (_Jv_word*) _Jv_AllocBytesChecked (pool_count * sizeof (_Jv_word));
def->constants.tags = pool_tags;
def->constants.data = pool_data;
check_tag (utf_index, JV_CONSTANT_Utf8);
unsigned char *utf_data = bytes + offsets[utf_index];
int len = get2u (utf_data);
- pool_data[i] = (void*)_Jv_makeUtf8Const ((char*)(utf_data+2), len);
+ pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
pool_tags[i] = JV_CONSTANT_String;
}
else
structure we are currently defining */
unsigned char *pool_tags = (unsigned char*) def->constants.tags;
- void **pool_data = (void**) def->constants.data;
+ _Jv_word *pool_data = def->constants.data;
/* this entry was already prepared */
if (pool_tags[index] == this_tag)
buffer[i] = (char) s[i];
}
- pool_data[index] = (void*)_Jv_makeUtf8Const (buffer, len);
+ pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
pool_tags[index] = JV_CONSTANT_Utf8;
}
break;
prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
if (verify)
- _Jv_VerifyClassName ((_Jv_Utf8Const*)pool_data[utf_index]);
+ _Jv_VerifyClassName (pool_data[utf_index].utf8);
- pool_data[index] = pool_data[utf_index];
+ pool_data[index].utf8 = pool_data[utf_index].utf8;
pool_tags[index] = JV_CONSTANT_Class;
}
break;
if (verify)
{
_Jv_ushort name_index, type_index;
- _Jv_loadIndexes ((const void**)&pool_data[nat_index],
+ _Jv_loadIndexes (&pool_data[nat_index],
name_index, type_index);
if (this_tag == JV_CONSTANT_Fieldref)
- _Jv_VerifyFieldSignature
- ((_Jv_Utf8Const*)pool_data[type_index]);
+ _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
else
- _Jv_VerifyMethodSignature
- ((_Jv_Utf8Const*)pool_data[type_index]);
+ _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
- _Jv_Utf8Const* name = (_Jv_Utf8Const*)pool_data[name_index];
+ _Jv_Utf8Const* name = pool_data[name_index].utf8;
if (this_tag != JV_CONSTANT_Fieldref
&& ( _Jv_equalUtf8Consts (name, clinit_name)
|| _Jv_equalUtf8Consts (name, init_name)))
/* ignore */;
else
- _Jv_VerifyIdentifier ((_Jv_Utf8Const*)pool_data[name_index]);
+ _Jv_VerifyIdentifier (pool_data[name_index].utf8);
}
_Jv_storeIndexes (&pool_data[index], class_index, nat_index);
_Jv_ClassReader::handleClassBegin
(int access_flags, int this_class, int super_class)
{
+ using namespace java::lang::reflect;
+
unsigned char *pool_tags = (unsigned char*) def->constants.tags;
- void **pool_data = (void**) def->constants.data;
+ _Jv_word *pool_data = def->constants.data;
check_tag (this_class, JV_CONSTANT_Class);
- _Jv_Utf8Const *loadedName = (_Jv_Utf8Const*)pool_data[this_class];
+ _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
// was ClassLoader.defineClass called with an expected class name?
if (def->name == 0)
}
def->accflags = access_flags;
- pool_data[this_class] = (void*)def;
+ pool_data[this_class].clazz = def;
pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
if (super_class == 0)
{
// interfaces have java.lang.Object as super.
- if (access_flags & INTERFACE)
+ if (access_flags & Modifier::INTERFACE)
{
def->superclass = (jclass)&ClassObject;
}
{
// load the super class
check_tag (super_class, JV_CONSTANT_Class);
- _Jv_Utf8Const* super_name =
- (_Jv_Utf8Const*)pool_data[super_class];
+ _Jv_Utf8Const* super_name = pool_data[super_class].utf8;
// load the super class using our defining loader
jclass the_super = _Jv_FindClass (super_name,
checkExtends (def, the_super);
def->superclass = the_super;
- pool_data[super_class] = (void*) the_super;
+ pool_data[super_class].clazz = the_super;
pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
}
void
_Jv_ClassReader::checkExtends (jclass sub, jclass super)
{
+ using namespace java::lang::reflect;
+
// having an interface or a final class as a superclass is no good
- if ((super->accflags & (INTERFACE | FINAL)) != 0)
+ if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
{
throw_incompatible_class_change_error (sub->getName ());
}
// if the super class is not public, we need to check some more
- if ((super->accflags & PUBLIC) == 0)
+ if ((super->accflags & Modifier::PUBLIC) == 0)
{
// With package scope, the classes must have the same
// class loader.
void _Jv_ClassReader::handleInterface (int if_number, int offset)
{
- void ** pool_data = def->constants.data;
+ _Jv_word * pool_data = def->constants.data;
unsigned char * pool_tags = (unsigned char*) def->constants.tags;
jclass the_interface;
if (pool_tags[offset] == JV_CONSTANT_Class)
{
- _Jv_Utf8Const* name = (_Jv_Utf8Const*) pool_data[offset];
+ _Jv_Utf8Const* name = pool_data[offset].utf8;
the_interface = _Jv_FindClass (name, def->loader);
}
else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
{
- the_interface = (jclass)pool_data[offset];
+ the_interface = pool_data[offset].clazz;
}
else
{
// allowed to implement that interface.
checkImplements (def, the_interface);
- pool_data[offset] = (void*)the_interface;
+ pool_data[offset].clazz = the_interface;
pool_tags[offset] = JV_CONSTANT_ResolvedClass;
def->interfaces[if_number] = the_interface;
void
_Jv_ClassReader::checkImplements (jclass sub, jclass super)
{
+ using namespace java::lang::reflect;
+
// well, it *must* be an interface
- if ((super->accflags & INTERFACE) == 0)
+ if ((super->accflags & Modifier::INTERFACE) == 0)
{
throw_incompatible_class_change_error (sub->getName ());
}
// if it has package scope, it must also be defined by the
// same loader.
- if ((super->accflags & PUBLIC) == 0)
+ if ((super->accflags & Modifier::PUBLIC) == 0)
{
if ( sub->loader != super->loader
|| !_Jv_ClassNameSamePackage (sub->name, super->name))
int name,
int desc)
{
- void **const pool_data = def->constants.data;
+ using namespace java::lang::reflect;
+
+ _Jv_word *pool_data = def->constants.data;
_Jv_Field *field = &def->fields[field_no];
- _Jv_Utf8Const *field_name = (_Jv_Utf8Const*) pool_data[name];
+ _Jv_Utf8Const *field_name = pool_data[name].utf8;
#ifndef COMPACT_FIELDS
field->name = field_name;
_Jv_VerifyIdentifier (field_name);
// ignore flags we don't know about.
- field->flags = flags & ALL_FLAGS;
+ field->flags = flags & Modifier::ALL_FLAGS;
if (verify)
{
- if (field->flags & (SYNCHRONIZED|NATIVE|INTERFACE|ABSTRACT))
+ if (field->flags & (Modifier::SYNCHRONIZED
+ | Modifier::NATIVE
+ | Modifier::INTERFACE
+ | Modifier::ABSTRACT))
throw_class_format_error ("erroneous field access flags");
- if (1 < ( ((field->flags & PUBLIC) ? 1 : 0)
- +((field->flags & PRIVATE) ? 1 : 0)
- +((field->flags & PROTECTED) ? 1 : 0)))
+ if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
+ +((field->flags & Modifier::PRIVATE) ? 1 : 0)
+ +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
throw_class_format_error ("erroneous field access flags");
}
- _Jv_Utf8Const* sig = (_Jv_Utf8Const*) pool_data[desc];
+ _Jv_Utf8Const* sig = pool_data[desc].utf8;
if (verify)
_Jv_VerifyFieldSignature (sig);
void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
int value)
{
+ using namespace java::lang::reflect;
+
_Jv_Field *field = &def->fields[field_index];
- if ((field->flags & (STATIC|FINAL|PRIVATE)) == 0)
+ if ((field->flags & (Modifier::STATIC
+ | Modifier::FINAL
+ | Modifier::PRIVATE)) == 0)
{
// Ignore, as per vmspec #4.7.2
return;
void _Jv_ClassReader::handleFieldsEnd ()
{
+ using namespace java::lang::reflect;
+
// We need to reorganize the fields so that the static ones are first,
// to conform to GCJ class layout.
while (low < high)
{
// go forward on low, while it's a static
- while (low < high && (fields[low].flags & STATIC) != 0)
+ while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
low++;
// go backwards on high, while it's a non-static
- while (low < high && (fields[high].flags & STATIC) == 0)
+ while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
high--;
if (low==high)
low += 1;
}
- if ((fields[low].flags & STATIC) != 0)
+ if ((fields[low].flags & Modifier::STATIC) != 0)
low += 1;
def->static_field_count = low;
-void _Jv_ClassReader::handleMethodsBegin (int count)
+void
+_Jv_ClassReader::handleMethodsBegin (int count)
{
def->methods = (_Jv_Method*)
_Jv_AllocBytesChecked (sizeof (_Jv_Method)*count);
- def->interpreted_methods = (_Jv_InterpMethod**)
- _Jv_AllocBytesChecked (sizeof (_Jv_InterpMethod*) * count);
+ def->interpreted_methods
+ = (_Jv_MethodBase **) _Jv_AllocBytesChecked (sizeof (_Jv_MethodBase *)
+ * count);
for (int i = 0; i < count; i++)
def->interpreted_methods[i] = 0;
void _Jv_ClassReader::handleMethod
(int mth_index, int accflags, int name, int desc)
{
- void **const pool_data = def->constants.data;
+ using namespace java::lang::reflect;
+
+ _Jv_word *pool_data = def->constants.data;
_Jv_Method *method = &def->methods[mth_index];
check_tag (name, JV_CONSTANT_Utf8);
prepare_pool_entry (name, JV_CONSTANT_Utf8);
- method->name = (_Jv_Utf8Const*)pool_data[name];
+ method->name = pool_data[name].utf8;
check_tag (desc, JV_CONSTANT_Utf8);
prepare_pool_entry (desc, JV_CONSTANT_Utf8);
- method->signature = (_Jv_Utf8Const*)pool_data[desc];
+ method->signature = pool_data[desc].utf8;
// ignore unknown flags
- method->accflags = accflags & ALL_FLAGS;
+ method->accflags = accflags & Modifier::ALL_FLAGS;
// intialize...
method->ncode = 0;
_Jv_VerifyMethodSignature (method->signature);
- if (method->accflags & (VOLATILE|TRANSIENT|INTERFACE))
+ if (method->accflags & (Modifier::VOLATILE
+ | Modifier::TRANSIENT
+ | Modifier::INTERFACE))
throw_class_format_error ("erroneous method access flags");
- if (1 < ( ((method->accflags & PUBLIC) ? 1 : 0)
- +((method->accflags & PRIVATE) ? 1 : 0)
- +((method->accflags & PROTECTED) ? 1 : 0)))
+ if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
+ +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
+ +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
throw_class_format_error ("erroneous method access flags");
}
}
(int method_index, int exc_index,
int start_pc, int end_pc, int handler_pc, int catch_type)
{
- _Jv_InterpMethod *method = def->interpreted_methods[method_index];
+ _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
+ (def->interpreted_methods[method_index]);
_Jv_InterpException *exc = method->exceptions ();
exc[exc_index].start_pc = start_pc;
void _Jv_ClassReader::handleMethodsEnd ()
{
+ using namespace java::lang::reflect;
+
for (int i = 0; i < def->method_count; i++)
{
_Jv_Method *method = &def->methods[i];
- if (method->accflags & (NATIVE|ABSTRACT))
+ if ((method->accflags & Modifier::NATIVE) != 0)
{
if (def->interpreted_methods[i] != 0)
- throw_class_format_error ("code provided "
- "for abstract or native method");
+ throw_class_format_error ("code provided for native method");
+ else
+ {
+ _Jv_JNIMethod *m = (_Jv_JNIMethod *)
+ _Jv_AllocBytesChecked (sizeof (_Jv_JNIMethod));
+ m->defining_class = def;
+ m->self = method;
+ m->function = NULL;
+ def->interpreted_methods[i] = m;
+ }
+ }
+ else if ((method->accflags & Modifier::ABSTRACT) != 0)
+ {
+ if (def->interpreted_methods[i] != 0)
+ throw_class_format_error ("code provided for abstract method");
}
else
{
if (def->interpreted_methods[i] == 0)
- throw_class_format_error ("abstract or native method "
- "with no code");
+ throw_class_format_error ("method with no code");
}
}
unsigned char *limit = ptr+length;
int ch;
+ if ('[' == UTF8_PEEK (ptr, limit))
+ {
+ if (! _Jv_VerifyOne (++ptr, limit, false))
+ throw_class_format_error ("erroneous class name");
+ else
+ return;
+ }
+
next_level:
do {
if ((ch = UTF8_GET (ptr, limit))==-1)