1999-04-07 16:42:40 +02:00
|
|
|
// Functions for Exception Support for Java.
|
|
|
|
|
|
|
|
/* Copyright (C) 1998, 1999 Cygnus Solutions
|
|
|
|
|
|
|
|
This file is part of libgcj.
|
|
|
|
|
|
|
|
This software is copyrighted work licensed under the terms of the
|
|
|
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|
|
|
details. */
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "exception"
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
#include <java/lang/Class.h>
|
|
|
|
#include <java/lang/NullPointerException.h>
|
1999-09-11 00:03:10 +02:00
|
|
|
#include <gcj/cni.h>
|
1999-04-07 16:42:40 +02:00
|
|
|
#include <jvm.h>
|
|
|
|
|
|
|
|
// eh-common.h needs gansidecl.h.
|
|
|
|
#include "gansidecl.h"
|
|
|
|
#include "eh-common.h"
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
__eh_info eh_info;
|
|
|
|
void *value;
|
|
|
|
} java_eh_info;
|
|
|
|
|
|
|
|
|
|
|
|
/* Language-specific EH info pointer, throw routine, and language/version
|
|
|
|
info routines. All defined in libgcc2. */
|
|
|
|
|
|
|
|
extern "C" java_eh_info **__get_eh_info ();
|
|
|
|
extern "C" void __throw () __attribute__ ((__noreturn__));
|
|
|
|
extern "C" short __get_eh_table_version (void *table);
|
|
|
|
extern "C" short __get_eh_table_language (void *table);
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" void * malloc (size_t);
|
|
|
|
extern "C" void free (void *);
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" void *
|
|
|
|
_Jv_type_matcher (java_eh_info *info, void* match_info,
|
|
|
|
void *exception_table)
|
|
|
|
{
|
|
|
|
if (__get_eh_table_language (exception_table) != EH_LANG_Java)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* we don't worry about version info yet, there is only one version! */
|
|
|
|
|
|
|
|
if (match_info != NULL)
|
|
|
|
{
|
|
|
|
// The match_info is either a (java::lang::Class*) or
|
|
|
|
// match_info is one more than a (Utf8Const*).
|
|
|
|
if (sizeof(void*) != sizeof(size_t))
|
|
|
|
abort();
|
|
|
|
size_t mi = (size_t) match_info;
|
|
|
|
if ((mi & 1) != 0)
|
|
|
|
match_info = _Jv_FindClass ((Utf8Const*) (mi - 1), NULL);
|
|
|
|
if (! _Jv_IsInstanceOf ((jobject) info->value, (jclass) match_info))
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return info->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compiler hook to return a pointer to java exception object. The value
|
|
|
|
is cleared, so if the exception needs to be rethrown, it should be set
|
|
|
|
again */
|
|
|
|
|
|
|
|
extern "C" void *
|
|
|
|
_Jv_exception_info (void)
|
|
|
|
{
|
|
|
|
java_eh_info *info = *(__get_eh_info ());
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
if (info == NULL)
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
ptr = info->value;
|
|
|
|
|
|
|
|
/* clear the value so another throw is an error */
|
|
|
|
info->value = NULL;
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Allocate an exception info structure for java. Called the first time
|
|
|
|
an exception is thrown. */
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
_Jv_eh_alloc ()
|
|
|
|
{
|
|
|
|
/* FIXME: we should use _Jv_AllocBytes here. However, libgcc2
|
|
|
|
apparently can sometimes free() this value itself. */
|
|
|
|
java_eh_info *p = (java_eh_info *) malloc (sizeof (java_eh_info));
|
|
|
|
if (p == 0)
|
|
|
|
terminate ();
|
|
|
|
|
|
|
|
p->value = 0;
|
|
|
|
java_eh_info ** info_ptr = __get_eh_info ();
|
|
|
|
|
|
|
|
/* There should NOT be an exception info pointer already. */
|
|
|
|
if (*info_ptr != NULL)
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
*info_ptr = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Deallocate the current exception info structure. Called at shutdown time. */
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
_Jv_eh_free ()
|
|
|
|
{
|
|
|
|
java_eh_info ** info_ptr = __get_eh_info ();
|
|
|
|
if (*info_ptr == NULL)
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
/* FIXME: ideally we should just let the GC handle this. */
|
|
|
|
free (*info_ptr);
|
|
|
|
*info_ptr = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Perform a throw, Java style. Throw will unwind through this call, so
|
|
|
|
there better not be any handlers or exception thrown here. */
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize an __eh_info structure with this libraries matching info. */
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
_Jv_setup_eh_info (__eh_info *)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
_Jv_Throw (void *value)
|
|
|
|
{
|
|
|
|
if (value == NULL)
|
|
|
|
value = (void *) new java::lang::NullPointerException ();
|
|
|
|
java_eh_info *ehinfo = *(__get_eh_info ());
|
|
|
|
if (ehinfo == NULL)
|
|
|
|
{
|
|
|
|
_Jv_eh_alloc ();
|
|
|
|
ehinfo = *(__get_eh_info ());
|
|
|
|
}
|
1999-08-03 02:30:53 +02:00
|
|
|
ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
|
1999-04-07 16:42:40 +02:00
|
|
|
ehinfo->eh_info.language = EH_LANG_Java;
|
|
|
|
ehinfo->eh_info.version = 1;
|
|
|
|
ehinfo->value = value;
|
|
|
|
__throw();
|
|
|
|
}
|