From e164eae76e4e677e729d62cf39e1c51e4ef7f311 Mon Sep 17 00:00:00 2001 From: aph Date: Fri, 24 Oct 2003 09:29:43 +0000 Subject: 2003-10-22 Andrew Haley * lang.c (LANG_HOOKS_GET_CALLEE_FNDECL): New. (java_get_callee_fndecl): New. * jcf-parse.c (java_parse_file): Call emit_catch_table(). * java-tree.h (ctable_decl): New. (catch_classes): New. (java_tree_index): Add JTI_CTABLE_DECL, JTI_CATCH_CLASSES. * decl.c (java_init_decl_processing): Add catch_class_type. Add ctable_decl. Add catch_classes field. * class.c (build_indirect_class_ref): Break out from build_class_ref. (make_field_value): Check flag_indirect_dispatch. (make_class_data): Ditto. Tidy uses of PUSH_FIELD_VALUE. Add field catch_classes. (make_catch_class_record): New. * java-tree.h (PUSH_FIELD_VALUE): Tidy. 2003-10-22 Andrew Haley * java/lang/natClass.cc (initializeClass): Call _Jv_linkExceptionClassTable. (_Jv_LinkSymbolTable): Call )_Jv_ThrowNoSuchMethodError. Call _Jv_Defer_Resolution on a method whose ncode is NULL. (_Jv_linkExceptionClassTable): New function. (_Jv_LayoutVTableMethods): If superclass looks like a constant pool entry, look it up. * java/lang/Class.h (struct _Jv_CatchClass): New. (_Jv_linkExceptionClassTable): New friend. (_Jv_Defer_Resolution): New friend. (class Class.catch_classes): New field. * include/java-interp.h (Jv_Defer_Resolution): New method. (_Jv_PrepareClass): Make a friend of _Jv_MethodBase. (_Jv_MethodBase.deferred): New field. (_Jv_Defer_Resolution): New function. * resolve.cc (_Jv_PrepareClass): Resolve deferred handlers. * exception.cc (get_ttype_entry): Change return type to void**. (PERSONALITY_FUNCTION): Remove all code related to using a Utf8Const* for a match type. Change match type to be a pointer to a pointer, rather than a pointer to a Class. * defineclass.cc (handleCodeAttribute): Initialize method->deferred. (handleMethodsEnd): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72886 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/java/lang/Class.h | 10 +++++++ libjava/java/lang/natClass.cc | 65 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 5 deletions(-) (limited to 'libjava/java') diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index cdfdd7d2349..01761af5cec 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -131,6 +131,12 @@ struct _Jv_AddressTable void *addresses[]; }; +struct _Jv_CatchClass +{ + java::lang::Class **address; + _Jv_Utf8Const *classname; +}; + #define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1) #define JV_CLASS(Obj) ((jclass) (*(_Jv_VTable **) Obj)->clas) @@ -336,6 +342,7 @@ private: friend void _Jv_LayoutVTableMethods (jclass klass); friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *); friend void _Jv_MakeVTable (jclass); + friend void _Jv_linkExceptionClassTable (jclass); friend jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass, jint flags); @@ -365,6 +372,8 @@ private: friend void _Jv_PrepareClass (jclass); friend void _Jv_PrepareMissingMethods (jclass base, jclass iface_class); + friend void _Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **); + friend class _Jv_ClassReader; friend class _Jv_InterpClass; friend class _Jv_InterpMethod; @@ -414,6 +423,7 @@ private: _Jv_MethodSymbol *otable_syms; _Jv_AddressTable *atable; _Jv_MethodSymbol *atable_syms; + _Jv_CatchClass *catch_classes; // Interfaces implemented by this class. jclass *interfaces; // The class loader for this class. diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index c9b70147b61..2d80ce2133b 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -12,6 +12,7 @@ details. */ #include #include +#include #pragma implementation "Class.h" @@ -56,7 +57,7 @@ details. */ #include #include - +#include using namespace gcj; @@ -796,6 +797,8 @@ java::lang::Class::initializeClass (void) if (otable || atable) _Jv_LinkSymbolTable(this); + _Jv_linkExceptionClassTable (this); + // Steps 8, 9, 10, 11. try { @@ -1541,14 +1544,18 @@ _Jv_LinkSymbolTable(jclass klass) for (index = 0; sym = klass->otable_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; - // FIXME: This should be special index for ThrowNoSuchMethod(). - klass->otable->offsets[index] = -1; - + { + static char *bounce = (char *)_Jv_ThrowNoSuchMethodError; + ptrdiff_t offset = (char *)(klass->vtable) - bounce; + klass->otable->offsets[index] = offset; + } + if (target_class == NULL) continue; @@ -1658,6 +1665,7 @@ _Jv_LinkSymbolTable(jclass klass) 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; @@ -1687,7 +1695,13 @@ _Jv_LinkSymbolTable(jclass klass) sym.signature); if (meth != NULL) - klass->atable->addresses[index] = meth->ncode; + { + if (meth->ncode) // Maybe abstract? + klass->atable->addresses[index] = meth->ncode; + else if (_Jv_IsInterpretedClass (target_class)) + _Jv_Defer_Resolution (target_class, meth, + &klass->atable->addresses[index]); + } else klass->atable->addresses[index] = (void *)_Jv_ThrowNoSuchMethodError; @@ -1743,6 +1757,27 @@ _Jv_LinkSymbolTable(jclass klass) } } + +// 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; +} + + // Returns true if METH should get an entry in a VTable. static jboolean isVirtualMethod (_Jv_Method *meth) @@ -1772,6 +1807,26 @@ _Jv_LayoutVTableMethods (jclass klass) 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); + } + } + else + superclass = klass->constants.data[(int)superclass].clazz; + } + if (superclass != NULL && superclass->vtable_method_count == -1) { JvSynchronize sync (superclass); -- cgit v1.2.3