- continue;
- }
-
- // try fields
- {
- _Jv_Field *the_field = NULL;
-
- for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
- {
- for (int i = 0; i < cls->field_count; i++)
- {
- _Jv_Field *field = &cls->fields[i];
- if (! _Jv_equalUtf8Consts (field->name, sym.name))
- continue;
-
- // FIXME: What access checks should we perform here?
-// if (_Jv_CheckAccess (klass, cls, field->flags))
-// {
-
- if (!field->isResolved ())
- _Jv_ResolveField (field, cls->loader);
-
-// if (field_type != 0 && field->type != field_type)
-// throw new java::lang::LinkageError
-// (JvNewStringLatin1
-// ("field type mismatch with different loaders"));
-
- the_field = field;
- goto end_of_field_search;
- }
- }
- end_of_field_search:
- if (the_field != NULL)
- {
- if (the_field->flags & 0x0008 /* Modifier::STATIC */)
- {
- throw new java::lang::IncompatibleClassChangeError;
- }
- else
- {
- klass->otable->offsets[index] = the_field->u.boffset;
- }
- }
- else
- {
- throw new java::lang::NoSuchFieldError
- (_Jv_NewStringUtf8Const (sym.name));
- }
- }
- }
-
- atable:
- if (klass->atable == NULL
- || klass->atable->state != 0)
- return;
-
- klass->atable->state = 1;
-
- for (index = 0; sym = klass->atable_syms[index], sym.name != NULL; index++)
- {
- // FIXME: Why are we passing NULL as the class loader?
- jclass target_class = _Jv_FindClass (sym.class_name, NULL);
- _Jv_Method *meth = NULL;
- const _Jv_Utf8Const *signature = sym.signature;
-
- // ??? Setting this pointer to null will at least get us a
- // NullPointerException
- klass->atable->addresses[index] = NULL;
-
- if (target_class == NULL)
- continue;
-
- // We're looking for a static field or a static method, and we
- // can tell which is needed by looking at the signature.
- if (signature->length >= 2
- && signature->data[0] == '(')
- {
- // If the target class does not have a vtable_method_count yet,
- // then we can't tell the offsets for its methods, so we must lay
- // it out now.
- if (target_class->vtable_method_count == -1)
- {
- JvSynchronize sync (target_class);
- _Jv_LayoutVTableMethods (target_class);
- }
-
- meth = _Jv_LookupDeclaredMethod(target_class, sym.name,
- sym.signature);
-
- if (meth != NULL)
- {
- if (meth->ncode) // Maybe abstract?
- klass->atable->addresses[index] = meth->ncode;
-#ifdef INTERPRETER
- else if (_Jv_IsInterpretedClass (target_class))
- _Jv_Defer_Resolution (target_class, meth,
- &klass->atable->addresses[index]);
-#endif
- }
- else
- klass->atable->addresses[index] = (void *)_Jv_ThrowNoSuchMethodError;
-
- continue;
- }
-
- // try fields
- {
- _Jv_Field *the_field = NULL;
-
- for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
- {
- for (int i = 0; i < cls->field_count; i++)
- {
- _Jv_Field *field = &cls->fields[i];
- if (! _Jv_equalUtf8Consts (field->name, sym.name))
- continue;
-
- // FIXME: What access checks should we perform here?
-// if (_Jv_CheckAccess (klass, cls, field->flags))
-// {
-
- if (!field->isResolved ())
- _Jv_ResolveField (field, cls->loader);
-
-// if (field_type != 0 && field->type != field_type)
-// throw new java::lang::LinkageError
-// (JvNewStringLatin1
-// ("field type mismatch with different loaders"));
-
- the_field = field;
- goto end_of_static_field_search;
- }
- }
- end_of_static_field_search:
- if (the_field != NULL)
- {
- if (the_field->flags & 0x0008 /* Modifier::STATIC */)
- {
- klass->atable->addresses[index] = the_field->u.addr;
- }
- else
- {
- throw new java::lang::IncompatibleClassChangeError;
- }
- }
- else
- {
- throw new java::lang::NoSuchFieldError
- (_Jv_NewStringUtf8Const (sym.name));
- }
- }
- }
-}
-
-
-// For each catch_record in the list of caught classes, fill in the
-// address field.
-void
-_Jv_linkExceptionClassTable (jclass self)
-{
- struct _Jv_CatchClass *catch_record = self->catch_classes;
- if (!catch_record || catch_record->classname)
- return;
- catch_record++;
- while (catch_record->classname)
- {
- jclass target_class = _Jv_FindClass (catch_record->classname,
- self->getClassLoaderInternal ());
- *catch_record->address = target_class;
- catch_record++;
- }
- self->catch_classes->classname = (_Jv_Utf8Const *)-1;
-}
-
-// This is put in empty vtable slots.
-static void
-_Jv_abstractMethodError (void)
-{
- throw new java::lang::AbstractMethodError();
-}
-
-// Prepare virtual method declarations in KLASS, and any superclasses as
-// required, by determining their vtable index, setting method->index, and
-// finally setting the class's vtable_method_count. Must be called with the
-// lock for KLASS held.
-void
-_Jv_LayoutVTableMethods (jclass klass)
-{
- if (klass->vtable != NULL || klass->isInterface()
- || klass->vtable_method_count != -1)
- return;
-
- jclass superclass = klass->superclass;
-
- typedef unsigned int uaddr __attribute__ ((mode (pointer)));
-
- // If superclass looks like a constant pool entry,
- // resolve it now.
- if ((uaddr)superclass < (uaddr)klass->constants.size)
- {
- if (klass->state < JV_STATE_LINKED)
- {
- _Jv_Utf8Const *name = klass->constants.data[(int)superclass].utf8;
- superclass = _Jv_FindClass (name, klass->loader);
- if (! superclass)
- {
- jstring str = _Jv_NewStringUTF (name->data);
- throw new java::lang::NoClassDefFoundError (str);
- }