Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: loader.c 7692 2007-04-12 14:47:24Z twisti $
-
*/
#include "mm/memory.h"
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "native/llni.h"
+
+#include "threads/lock-common.h"
#include "toolbox/logging.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/global.h"
+#include "vm/primitive.h"
#include "vm/stringlocal.h"
#include "vm/vm.h"
#endif
#include "vmcore/classcache.h"
+#include "vmcore/field.h"
#include "vmcore/linker.h"
#include "vmcore/loader.h"
+#include "vmcore/method.h"
#include "vmcore/options.h"
#include "vmcore/rt-timing.h"
for (lce = list_first(list_classpath_entries); lce != NULL;
lce = list_next(list_classpath_entries, lce))
if (lce->type == CLASSPATH_ARCHIVE)
- lock_init_object_lock((java_objectheader *) lce);
+ LOCK_INIT_OBJECT_LOCK(lce);
#endif
/* load some important classes */
if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
return false;
+# if defined(WITH_CLASSPATH_SUN)
+ if (!(class_sun_reflect_MagicAccessorImpl =
+ load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
+ return false;
+# endif
+
if (!(arrayclass_java_lang_Object =
load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
return false;
+
+#if defined(ENABLE_ANNOTATIONS)
+ /* needed by annotation support */
+ if (!(class_sun_reflect_ConstantPool =
+ load_class_bootstrap(utf_sun_reflect_ConstantPool)))
+ return false;
+
+#if defined(WITH_CLASSPATH_GNU)
+ /* needed by GNU Classpaths annotation support */
+ if (!(class_sun_reflect_annotation_AnnotationParser =
+ load_class_bootstrap(utf_sun_reflect_annotation_AnnotationParser)))
+ return false;
+#endif
#endif
+#endif
+
return true;
}
cptags[forward_classes->thisindex] = CONSTANT_Class;
- if (opt_eager) {
- classinfo *tc;
-
- if (!(tc = load_class_bootstrap(name)))
- return false;
-
- /* link the class later, because we cannot link the class currently
- loading */
- list_add_first(&unlinkedclasses, tc);
- }
-
/* the classref is created later */
cpinfos[forward_classes->thisindex] = name;
#endif /* defined(ENABLE_JAVASE) */
-/* load_field ******************************************************************
-
- Load everything about a class field from the class file and fill a
- 'fieldinfo' structure. For static fields, space in the data segment
- is allocated.
-
-*******************************************************************************/
-
-#define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
-
-static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
-{
- classinfo *c;
- u4 attrnum, i;
- u4 jtype;
- u4 pindex = field_load_NOVALUE; /* constantvalue_index */
- utf *u;
-
- c = cb->class;
-
- if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
- return false;
-
- f->flags = suck_u2(cb);
-
- if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
- return false;
-
- f->name = u;
-
- if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
- return false;
-
- f->descriptor = u;
- f->parseddesc = NULL;
-
- if (!descriptor_pool_add(descpool, u, NULL))
- return false;
-
- /* descriptor_pool_add accepts method descriptors, so we have to check */
- /* against them here before the call of descriptor_to_basic_type below. */
- if (u->text[0] == '(') {
- exceptions_throw_classformaterror(c, "Method descriptor used for field");
- return false;
- }
-
-#ifdef ENABLE_VERIFIER
- if (opt_verify) {
- /* check name */
- if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
- exceptions_throw_classformaterror(c,
- "Illegal Field name \"%s\"",
- f->name->text);
- return false;
- }
-
- /* check flag consistency */
- i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
-
- if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
- ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
- exceptions_throw_classformaterror(c,
- "Illegal field modifiers: 0x%X",
- f->flags);
- return false;
- }
-
- if (c->flags & ACC_INTERFACE) {
- if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
- != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
- f->flags & ACC_TRANSIENT) {
- exceptions_throw_classformaterror(c,
- "Illegal field modifiers: 0x%X",
- f->flags);
- return false;
- }
- }
- }
-#endif /* ENABLE_VERIFIER */
-
- f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
- f->offset = 0; /* offset from start of object */
- f->class = c;
-
- switch (f->type) {
- case TYPE_INT:
- f->value.i = 0;
- break;
-
- case TYPE_FLT:
- f->value.f = 0.0;
- break;
-
- case TYPE_DBL:
- f->value.d = 0.0;
- break;
-
- case TYPE_ADR:
- f->value.a = NULL;
- if (!(f->flags & ACC_STATIC))
- c->flags |= ACC_CLASS_HAS_POINTERS;
- break;
-
- case TYPE_LNG:
-#if U8_AVAILABLE
- f->value.l = 0;
-#else
- f->value.l.low = 0;
- f->value.l.high = 0;
-#endif
- break;
- }
-
- /* read attributes */
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- attrnum = suck_u2(cb);
- for (i = 0; i < attrnum; i++) {
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
- return false;
-
- if (u == utf_ConstantValue) {
- if (!suck_check_classbuffer_size(cb, 4 + 2))
- return false;
-
- /* check attribute length */
-
- if (suck_u4(cb) != 2) {
- exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
- return false;
- }
-
- /* constant value attribute */
-
- if (pindex != field_load_NOVALUE) {
- exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
- return false;
- }
-
- /* index of value in constantpool */
-
- pindex = suck_u2(cb);
-
- /* initialize field with value from constantpool */
- switch (jtype) {
- case TYPE_INT: {
- constant_integer *ci;
-
- if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
- return false;
-
- f->value.i = ci->value;
- }
- break;
-
- case TYPE_LNG: {
- constant_long *cl;
-
- if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
- return false;
-
- f->value.l = cl->value;
- }
- break;
-
- case TYPE_FLT: {
- constant_float *cf;
-
- if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
- return false;
-
- f->value.f = cf->value;
- }
- break;
-
- case TYPE_DBL: {
- constant_double *cd;
-
- if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
- return false;
-
- f->value.d = cd->value;
- }
- break;
-
- case TYPE_ADR:
- if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
- return false;
-
- /* create javastring from compressed utf8-string */
- f->value.a = literalstring_new(u);
- break;
-
- default:
- log_text("Invalid Constant - Type");
- }
- }
-#if defined(ENABLE_JAVASE)
- else if (u == utf_Signature) {
- /* Signature */
-
- if (!loader_load_attribute_signature(cb, &(f->signature)))
- return false;
- }
-#endif
- else {
- /* unknown attribute */
-
- if (!loader_skip_attribute_body(cb))
- return false;
- }
- }
-
- /* everything was ok */
-
- return true;
-}
-
-
-/* loader_load_method **********************************************************
-
- Loads a method from the class file and fills an existing
- 'methodinfo' structure. For native methods, the function pointer
- field is set to the real function pointer, for JavaVM methods a
- pointer to the compiler is used preliminarily.
-
- method_info {
- u2 access_flags;
- u2 name_index;
- u2 descriptor_index;
- u2 attributes_count;
- attribute_info attributes[attribute_count];
- }
-
- attribute_info {
- u2 attribute_name_index;
- u4 attribute_length;
- u1 info[attribute_length];
- }
-
- LineNumberTable_attribute {
- u2 attribute_name_index;
- u4 attribute_length;
- u2 line_number_table_length;
- {
- u2 start_pc;
- u2 line_number;
- } line_number_table[line_number_table_length];
- }
-
-*******************************************************************************/
-
-static bool loader_load_method(classbuffer *cb, methodinfo *m,
- descriptor_pool *descpool)
-{
- classinfo *c;
- int argcount;
- s4 i, j, k, l;
- utf *u;
- u2 name_index;
- u2 descriptor_index;
- u2 attributes_count;
- u2 attribute_name_index;
- utf *attribute_name;
- u2 code_attributes_count;
- u2 code_attribute_name_index;
- utf *code_attribute_name;
-
- /* get classinfo */
-
- c = cb->class;
-
-#if defined(ENABLE_THREADS)
- lock_init_object_lock(&m->header);
-#endif
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat)
- count_all_methods++;
-#endif
-
- /* all fields of m have been zeroed in load_class_from_classbuffer */
-
- m->class = c;
-
- if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
- return false;
-
- /* access flags */
-
- m->flags = suck_u2(cb);
-
- /* name */
-
- name_index = suck_u2(cb);
-
- if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
- return false;
-
- m->name = u;
-
- /* descriptor */
-
- descriptor_index = suck_u2(cb);
-
- if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
- return false;
-
- m->descriptor = u;
-
- if (!descriptor_pool_add(descpool, u, &argcount))
- return false;
-
-#ifdef ENABLE_VERIFIER
- if (opt_verify) {
- if (!is_valid_name_utf(m->name)) {
- exceptions_throw_classformaterror(c, "Method with invalid name");
- return false;
- }
-
- if (m->name->text[0] == '<' &&
- m->name != utf_init && m->name != utf_clinit) {
- exceptions_throw_classformaterror(c, "Method with invalid special name");
- return false;
- }
- }
-#endif /* ENABLE_VERIFIER */
-
- if (!(m->flags & ACC_STATIC))
- argcount++; /* count the 'this' argument */
-
-#ifdef ENABLE_VERIFIER
- if (opt_verify) {
- if (argcount > 255) {
- exceptions_throw_classformaterror(c, "Too many arguments in signature");
- return false;
- }
-
- /* check flag consistency */
- if (m->name != utf_clinit) {
- i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
-
- if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
- exceptions_throw_classformaterror(c,
- "Illegal method modifiers: 0x%X",
- m->flags);
- return false;
- }
-
- if (m->flags & ACC_ABSTRACT) {
- if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
- ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
- exceptions_throw_classformaterror(c,
- "Illegal method modifiers: 0x%X",
- m->flags);
- return false;
- }
- }
-
- if (c->flags & ACC_INTERFACE) {
- if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
- exceptions_throw_classformaterror(c,
- "Illegal method modifiers: 0x%X",
- m->flags);
- return false;
- }
- }
-
- if (m->name == utf_init) {
- if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
- ACC_NATIVE | ACC_ABSTRACT)) {
- exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
- return false;
- }
- }
- }
- }
-#endif /* ENABLE_VERIFIER */
-
- /* mark the method as monomorphic until further notice */
-
- m->flags |= ACC_METHOD_MONOMORPHIC;
-
- /* non-abstract methods have an implementation in this class */
-
- if (!(m->flags & ACC_ABSTRACT))
- m->flags |= ACC_METHOD_IMPLEMENTED;
-
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- /* attributes count */
-
- attributes_count = suck_u2(cb);
-
- for (i = 0; i < attributes_count; i++) {
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- /* attribute name index */
-
- attribute_name_index = suck_u2(cb);
-
- if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
- return false;
-
- if (attribute_name == utf_Code) {
- /* Code */
- if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
- exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
- return false;
- }
-
- if (m->jcode) {
- exceptions_throw_classformaterror(c, "Multiple Code attributes");
- return false;
- }
-
- if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
- return false;
-
- suck_u4(cb);
- m->maxstack = suck_u2(cb);
- m->maxlocals = suck_u2(cb);
-
- if (m->maxlocals < argcount) {
- exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
- return false;
- }
-
- if (!suck_check_classbuffer_size(cb, 4))
- return false;
-
- m->jcodelength = suck_u4(cb);
-
- if (m->jcodelength == 0) {
- exceptions_throw_classformaterror(c, "Code of a method has length 0");
- return false;
- }
-
- if (m->jcodelength > 65535) {
- exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
- return false;
- }
-
- if (!suck_check_classbuffer_size(cb, m->jcodelength))
- return false;
-
- m->jcode = MNEW(u1, m->jcodelength);
- suck_nbytes(m->jcode, cb, m->jcodelength);
-
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- m->rawexceptiontablelength = suck_u2(cb);
- if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
- return false;
-
- m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat) {
- count_vmcode_len += m->jcodelength + 18;
- count_extable_len +=
- m->rawexceptiontablelength * sizeof(raw_exception_entry);
- }
-#endif
-
- for (j = 0; j < m->rawexceptiontablelength; j++) {
- u4 idx;
- m->rawexceptiontable[j].startpc = suck_u2(cb);
- m->rawexceptiontable[j].endpc = suck_u2(cb);
- m->rawexceptiontable[j].handlerpc = suck_u2(cb);
-
- idx = suck_u2(cb);
- if (!idx) {
- m->rawexceptiontable[j].catchtype.any = NULL;
-
- } else {
- /* the classref is created later */
- if (!(m->rawexceptiontable[j].catchtype.any =
- (utf*)class_getconstant(c, idx, CONSTANT_Class)))
- return false;
- }
- }
-
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- /* code attributes count */
-
- code_attributes_count = suck_u2(cb);
-
- for (k = 0; k < code_attributes_count; k++) {
- if (!suck_check_classbuffer_size(cb, 2))
- return false;
-
- /* code attribute name index */
-
- code_attribute_name_index = suck_u2(cb);
-
- if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
- return false;
-
- /* check which code attribute */
-
- if (code_attribute_name == utf_LineNumberTable) {
- /* LineNumberTable */
- if (!suck_check_classbuffer_size(cb, 4 + 2))
- return false;
-
- /* attribute length */
-
- (void) suck_u4(cb);
-
- /* line number table length */
-
- m->linenumbercount = suck_u2(cb);
-
- if (!suck_check_classbuffer_size(cb,
- (2 + 2) * m->linenumbercount))
- return false;
-
- m->linenumbers = MNEW(lineinfo, m->linenumbercount);
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat)
- size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
-#endif
-
- for (l = 0; l < m->linenumbercount; l++) {
- m->linenumbers[l].start_pc = suck_u2(cb);
- m->linenumbers[l].line_number = suck_u2(cb);
- }
- }
-#if defined(ENABLE_JAVASE)
- else if (code_attribute_name == utf_StackMapTable) {
- /* StackTableMap */
-
- if (!stackmap_load_attribute_stackmaptable(cb, m))
- return false;
- }
-#endif
- else {
- /* unknown code attribute */
-
- if (!loader_skip_attribute_body(cb))
- return false;
- }
- }
- }
- else if (attribute_name == utf_Exceptions) {
- /* Exceptions */
-
- if (m->thrownexceptions != NULL) {
- exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
- return false;
- }
-
- if (!suck_check_classbuffer_size(cb, 4 + 2))
- return false;
-
- /* attribute length */
-
- (void) suck_u4(cb);
-
- m->thrownexceptionscount = suck_u2(cb);
-
- if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
- return false;
-
- m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
-
- for (j = 0; j < m->thrownexceptionscount; j++) {
- /* the classref is created later */
- if (!((m->thrownexceptions)[j].any =
- (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
- return false;
- }
- }
-#if defined(ENABLE_JAVASE)
- else if (attribute_name == utf_Signature) {
- /* Signature */
-
- if (!loader_load_attribute_signature(cb, &(m->signature)))
- return false;
- }
-#endif
- else {
- /* unknown attribute */
-
- if (!loader_skip_attribute_body(cb))
- return false;
- }
- }
-
- if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
- exceptions_throw_classformaterror(c, "Missing Code attribute");
- return false;
- }
-
- /* initialize the hit countdown field */
-
-#if defined(ENABLE_REPLACEMENT)
- m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
-#endif
-
- /* everything was ok */
-
- return true;
-}
-
-
/* load_class_from_sysloader ***************************************************
Load the class with the given name using the system class loader
classinfo *load_class_from_sysloader(utf *name)
{
- methodinfo *m;
- java_objectheader *cl;
- classinfo *c;
+ methodinfo *m;
+ classloader *cl;
+ classinfo *c;
assert(class_java_lang_Object);
assert(class_java_lang_ClassLoader);
*******************************************************************************/
-classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
+classinfo *load_class_from_classloader(utf *name, classloader *cl)
{
- java_objectheader *o;
- classinfo *c;
- classinfo *tmpc;
- java_objectheader *string;
+ java_handle_t *o;
+ classinfo *c;
+ classinfo *tmpc;
+ java_handle_t *string;
#if defined(ENABLE_RT_TIMING)
struct timespec time_start, time_lookup, time_prepare, time_java,
time_cache;
case 'L':
/* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
- exceptions_throw_noclassdeffounderror(name);
+ exceptions_throw_classnotfoundexception(name);
return false;
}
RT_TIMING_GET_TIME(time_java);
- c = (classinfo *) o;
+ c = LLNI_classinfo_unwrap(o);
if (c != NULL) {
/* Store this class in the loaded class cache. If another
}
c = tmpc;
-
- } else {
- /* loadClass has thrown an exception. We must convert
- ClassNotFoundException into
- NoClassDefFoundException. */
-
- /* XXX Maybe we should have a flag that avoids this
- conversion for calling load_class_from_classloader from
- Class.forName. Currently we do a double conversion in
- these cases. */
-
- classnotfoundexception_to_noclassdeffounderror();
}
RT_TIMING_GET_TIME(time_cache);
/* lookup if this class has already been loaded */
- if ((r = classcache_lookup(NULL, name))) {
+ r = classcache_lookup(NULL, name);
+ if (r != NULL) {
RT_TIMING_GET_TIME(time_lookup);
RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
if (name->text[0] == '[') {
c = load_newly_created_array(c, NULL);
+
if (c == NULL)
return NULL;
+
assert(c->state & CLASS_LOADED);
RT_TIMING_GET_TIME(time_array);
if (name == utf_java_lang_Object)
vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
- exceptions_throw_noclassdeffounderror(name);
+ exceptions_throw_classnotfoundexception(name);
return NULL;
}
The super class and the interfaces implemented by this class need
not be loaded. The link is set later by the function 'class_link'.
- The loaded class is removed from the list 'unloadedclasses' and
- added to the list 'unlinkedclasses'.
-
SYNCHRONIZATION:
This function is NOT synchronized!
RT_TIMING_GET_TIME(time_setup);
/* load fields */
+
if (!suck_check_classbuffer_size(cb, 2))
goto return_exception;
c->fieldscount = suck_u2(cb);
-#if defined(ENABLE_GC_CACAO)
- c->fields = MNEW(fieldinfo, c->fieldscount);
+ c->fields = MNEW(fieldinfo, c->fieldscount);
+
MZERO(c->fields, fieldinfo, c->fieldscount);
-#else
- c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
-#endif
for (i = 0; i < c->fieldscount; i++) {
- if (!load_field(cb, &(c->fields[i]),descpool))
+ if (!field_load(cb, &(c->fields[i]), descpool))
goto return_exception;
}
RT_TIMING_GET_TIME(time_fields);
/* load methods */
+
if (!suck_check_classbuffer_size(cb, 2))
goto return_exception;
c->methodscount = suck_u2(cb);
- c->methods = MNEW(methodinfo, c->methodscount);
+ c->methods = MNEW(methodinfo, c->methodscount);
MZERO(c->methods, methodinfo, c->methodscount);
for (i = 0; i < c->methodscount; i++) {
- if (!loader_load_method(cb, &(c->methods[i]), descpool))
+ if (!method_load(cb, &(c->methods[i]), descpool))
goto return_exception;
}
*******************************************************************************/
-classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
+classinfo *load_newly_created_array(classinfo *c, classloader *loader)
{
classinfo *comp = NULL;
methodinfo *clone;
s4 namelen;
utf *u;
- text = c->name->text;
+ text = c->name->text;
namelen = c->name->blength;
/* Check array class name */
if ((namelen < 2) || (text[0] != '[')) {
- exceptions_throw_noclassdeffounderror(c->name);
+ exceptions_throw_classnotfoundexception(c->name);
return NULL;
}
/* c is an array of arrays. We have to create the component class. */
u = utf_new(text + 1, namelen - 1);
- if (!(comp = load_class_from_classloader(u, loader)))
+
+ comp = load_class_from_classloader(u, loader);
+
+ if (comp == NULL)
return NULL;
assert(comp->state & CLASS_LOADED);
- if (opt_eager)
- if (!link_class(c))
- return NULL;
-
/* the array's flags are that of the component class */
c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
c->classloader = comp->classloader;
/* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
- exceptions_throw_noclassdeffounderror(c->name);
+ exceptions_throw_classnotfoundexception(c->name);
return NULL;
}
assert(comp->state & CLASS_LOADED);
- if (opt_eager)
- if (!link_class(c))
- return NULL;
-
/* the array's flags are that of the component class */
c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
c->classloader = comp->classloader;
default:
/* c is an array of a primitive type */
- /* check for cases like `[II' */
- if (namelen > 2) {
- exceptions_throw_noclassdeffounderror(c->name);
+ /* check for cases like `[II' and whether the character is a
+ valid primitive type */
+
+ if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
+ exceptions_throw_classnotfoundexception(c->name);
return NULL;
}
c->super.cls = class_java_lang_Object;
#if defined(ENABLE_JAVASE)
- c->interfacescount = 2;
- c->interfaces = MNEW(classref_or_classinfo, 2);
- if (opt_eager) {
- classinfo *tc;
+ c->interfacescount = 2;
+ c->interfaces = MNEW(classref_or_classinfo, 2);
+ c->interfaces[0].cls = class_java_lang_Cloneable;
+ c->interfaces[1].cls = class_java_io_Serializable;
- tc = class_java_lang_Cloneable;
- assert(tc->state & CLASS_LOADED);
- list_add_first(&unlinkedclasses, tc);
- c->interfaces[0].cls = tc;
-
- tc = class_java_io_Serializable;
- assert(tc->state & CLASS_LOADED);
- list_add_first(&unlinkedclasses, tc);
- c->interfaces[1].cls = tc;
- }
- else {
- c->interfaces[0].cls = class_java_lang_Cloneable;
- c->interfaces[1].cls = class_java_io_Serializable;
- }
#elif defined(ENABLE_JAVAME_CLDC1_1)
- c->interfacescount = 0;
- c->interfaces = NULL;
+
+ c->interfacescount = 0;
+ c->interfaces = NULL;
+
#else
-#error unknow Java configuration
+# error unknow Java configuration
#endif
c->methodscount = 1;