mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
ab184b2a8f
commit
a7f3ff761f
|
|
@ -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>
|
2006-02-01 Robert Schuster <robertschuster@fsfe.org>
|
||||||
|
|
||||||
* link.cc:
|
* link.cc:
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ private:
|
||||||
static _Jv_Method *search_method_in_class (jclass, jclass,
|
static _Jv_Method *search_method_in_class (jclass, jclass,
|
||||||
_Jv_Utf8Const *,
|
_Jv_Utf8Const *,
|
||||||
_Jv_Utf8Const *);
|
_Jv_Utf8Const *);
|
||||||
|
static void *create_error_method(_Jv_Utf8Const *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -767,6 +767,7 @@ _Jv_ThrowNoSuchMethodError ()
|
||||||
throw new java::lang::NoSuchMethodError;
|
throw new java::lang::NoSuchMethodError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_LIBFFI
|
||||||
// A function whose invocation is prepared using libffi. It gets called
|
// A function whose invocation is prepared using libffi. It gets called
|
||||||
// whenever a static method of a missing class is invoked. The data argument
|
// whenever a static method of a missing class is invoked. The data argument
|
||||||
// holds a reference to a String denoting the missing class.
|
// holds a reference to a String denoting the missing class.
|
||||||
|
|
@ -777,14 +778,18 @@ _Jv_ThrowNoClassDefFoundErrorTrampoline(ffi_cif *,
|
||||||
void **,
|
void **,
|
||||||
void *data)
|
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
|
void
|
||||||
_Jv_ThrowNoClassDefFoundError()
|
_Jv_ThrowNoClassDefFoundError()
|
||||||
{
|
{
|
||||||
throw new java::lang::NoClassDefFoundError();
|
throw new java::lang::NoClassDefFoundError();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Throw a NoSuchFieldError. Called by compiler-generated code when
|
// Throw a NoSuchFieldError. Called by compiler-generated code when
|
||||||
// an otable entry is zero. OTABLE_INDEX is the index in the caller's
|
// 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.
|
// Functions for indirect dispatch (symbolic virtual binding) support.
|
||||||
|
|
||||||
// There are three tables, atable otable and itable. atable is an
|
// 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
|
// code in classes where the missing class is part of the
|
||||||
// execution environment as long as it is never referenced.
|
// execution environment as long as it is never referenced.
|
||||||
if (target_class == NULL)
|
if (target_class == NULL)
|
||||||
{
|
klass->atable->addresses[index] = create_error_method(sym.class_name);
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// We're looking for a static field or a static method, and we
|
// We're looking for a static field or a static method, and we
|
||||||
// can tell which is needed by looking at the signature.
|
// can tell which is needed by looking at the signature.
|
||||||
else if (signature->first() == '(' && signature->len() >= 2)
|
else if (signature->first() == '(' && signature->len() >= 2)
|
||||||
|
|
@ -1198,10 +1209,8 @@ _Jv_Linker::link_symbol_table (jclass klass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// TODO: Use _Jv_ThrowNoClassDefFoundErrorTrampoline to be able
|
|
||||||
// to print the class name.
|
|
||||||
klass->atable->addresses[index]
|
klass->atable->addresses[index]
|
||||||
= (void *) _Jv_ThrowNoClassDefFoundError;
|
= create_error_method(sym.class_name);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue