re PR libgcj/26073 (libjava fails to compile)

Fixes PR #26073.

2006-02-03  Robert Schuster  <robertschuster@fsfe.org>

	* include/jvm.h:
	(_Jv_Linker::create_error_method): New method declaration.
	* link.cc:
	(_Jv_Linker::create_error_method): New method.
	(_Jv_Linker::link_symbol_table): Use new method above.

From-SVN: r110543
This commit is contained in:
Robert Schuster 2006-02-03 13:47:51 +00:00 committed by Robert Schuster
parent ab184b2a8f
commit a7f3ff761f
3 changed files with 63 additions and 45 deletions

View File

@ -1,3 +1,11 @@
2006-02-03 Robert Schuster <robertschuster@fsfe.org>
* include/jvm.h:
(_Jv_Linker::create_error_method): New method declaration.
* link.cc:
(_Jv_Linker::create_error_method): New method.
(_Jv_Linker::link_symbol_table): Use new method above.
2006-02-01 Robert Schuster <robertschuster@fsfe.org>
* link.cc:

View File

@ -264,6 +264,7 @@ private:
static _Jv_Method *search_method_in_class (jclass, jclass,
_Jv_Utf8Const *,
_Jv_Utf8Const *);
static void *create_error_method(_Jv_Utf8Const *);
public:

View File

@ -767,6 +767,7 @@ _Jv_ThrowNoSuchMethodError ()
throw new java::lang::NoSuchMethodError;
}
#ifdef USE_LIBFFI
// A function whose invocation is prepared using libffi. It gets called
// whenever a static method of a missing class is invoked. The data argument
// holds a reference to a String denoting the missing class.
@ -777,14 +778,18 @@ _Jv_ThrowNoClassDefFoundErrorTrampoline(ffi_cif *,
void **,
void *data)
{
throw new java::lang::NoClassDefFoundError((jstring) data);
throw new java::lang::NoClassDefFoundError(
_Jv_NewStringUtf8Const( (_Jv_Utf8Const *) data));
}
#else
// A variant of the NoClassDefFoundError throwing method that can
// be used without libffi.
void
_Jv_ThrowNoClassDefFoundError()
{
throw new java::lang::NoClassDefFoundError();
}
#endif
// Throw a NoSuchFieldError. Called by compiler-generated code when
// an otable entry is zero. OTABLE_INDEX is the index in the caller's
@ -950,6 +955,51 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num)
}
void *
_Jv_Linker::create_error_method (_Jv_Utf8Const *class_name)
{
#ifdef USE_LIBFFI
// TODO: The following structs/objects are heap allocated are
// unreachable by the garbage collector:
// - cif, arg_types
ffi_closure *closure = (ffi_closure *) _Jv_Malloc( sizeof( ffi_closure ));
ffi_cif *cif = (ffi_cif *) _Jv_Malloc( sizeof( ffi_cif ));
// Pretends that we want to call a void (*) (void) function via
// ffi_call.
ffi_type **arg_types = (ffi_type **) _Jv_Malloc( sizeof( ffi_type * ));
arg_types[0] = &ffi_type_void;
// Initializes the cif and the closure. If that worked the closure is
// returned and can be used as a function pointer in a class' atable.
if (ffi_prep_cif (
cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, arg_types) == FFI_OK
&& (ffi_prep_closure (
closure, cif, _Jv_ThrowNoClassDefFoundErrorTrampoline,
class_name) == FFI_OK))
{
return closure;
}
else
{
java::lang::StringBuffer *buffer = new java::lang::StringBuffer();
buffer->append(
JvNewStringLatin1("Error setting up FFI closure"
" for static method of missing class: "));
buffer->append (_Jv_NewStringUtf8Const(class_name));
throw new java::lang::InternalError(buffer->toString());
}
#else
// Codepath for platforms which do not support (or want) libffi.
// You have to accept that it is impossible to provide the name
// of the missing class then.
return _Jv_ThrowNoClassDefFoundError;
#endif
}
// Functions for indirect dispatch (symbolic virtual binding) support.
// There are three tables, atable otable and itable. atable is an
@ -1118,46 +1168,7 @@ _Jv_Linker::link_symbol_table (jclass klass)
// code in classes where the missing class is part of the
// execution environment as long as it is never referenced.
if (target_class == NULL)
{
// TODO: The following structs/objects are heap allocated are
// unreachable by the garbage collector:
// - cif, arg_types
// - the Java string inside the if-statement
ffi_closure *closure =
(ffi_closure *) _Jv_Malloc( sizeof( ffi_closure ));
ffi_cif *cif = (ffi_cif *) _Jv_Malloc( sizeof( ffi_cif ));
// Pretends that we want to call a void (*) (void) function via
// ffi_call.
ffi_type **arg_types = (ffi_type **) _Jv_Malloc( sizeof( ffi_type * ));
arg_types[0] = &ffi_type_void;
// Initializes the cif and the closure. If that worked the closure is
// stored as a function pointer in the atable.
if ( ffi_prep_cif(cif, FFI_DEFAULT_ABI, 1,
&ffi_type_void, arg_types) == FFI_OK
&& (ffi_prep_closure
(closure, cif,
_Jv_ThrowNoClassDefFoundErrorTrampoline,
(void *) _Jv_NewStringUtf8Const(sym.class_name))
== FFI_OK))
{
klass->atable->addresses[index] = (void *) closure;
}
else
{
// If you land here it is possible that your architecture does
// not support the Closure API yet. Let's port it!
java::lang::StringBuffer *buffer = new java::lang::StringBuffer();
buffer->append
(JvNewStringLatin1("Error setting up FFI closure"
" for static method of missing class: "));
buffer->append (_Jv_NewStringUtf8Const(sym.class_name));
throw new java::lang::InternalError(buffer->toString());
}
}
klass->atable->addresses[index] = create_error_method(sym.class_name);
// We're looking for a static field or a static method, and we
// can tell which is needed by looking at the signature.
else if (signature->first() == '(' && signature->len() >= 2)
@ -1198,10 +1209,8 @@ _Jv_Linker::link_symbol_table (jclass klass)
}
}
else
// TODO: Use _Jv_ThrowNoClassDefFoundErrorTrampoline to be able
// to print the class name.
klass->atable->addresses[index]
= (void *) _Jv_ThrowNoClassDefFoundError;
= create_error_method(sym.class_name);
continue;
}