aboutsummaryrefslogtreecommitdiff
path: root/libjava/exception.cc
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>1999-04-07 14:42:40 +0000
committerTom Tromey <tromey@gcc.gnu.org>1999-04-07 14:42:40 +0000
commitee9dd3721be68b9fa63dea9aa5a1d86e66958cde (patch)
treed96801a16fdf03a5682ef98730fe333a46eef944 /libjava/exception.cc
parent140fa895c6b859f827fc4437b91775a82cd105fb (diff)
downloadgcc-ee9dd3721be68b9fa63dea9aa5a1d86e66958cde.zip
gcc-ee9dd3721be68b9fa63dea9aa5a1d86e66958cde.tar.gz
gcc-ee9dd3721be68b9fa63dea9aa5a1d86e66958cde.tar.bz2
Initial revision
From-SVN: r26263
Diffstat (limited to 'libjava/exception.cc')
-rw-r--r--libjava/exception.cc155
1 files changed, 155 insertions, 0 deletions
diff --git a/libjava/exception.cc b/libjava/exception.cc
new file mode 100644
index 0000000..644f80b
--- /dev/null
+++ b/libjava/exception.cc
@@ -0,0 +1,155 @@
+// 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>
+#include <cni.h>
+#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 ());
+ }
+ ehinfo->eh_info.match_function = _Jv_type_matcher;
+ ehinfo->eh_info.language = EH_LANG_Java;
+ ehinfo->eh_info.version = 1;
+ ehinfo->value = value;
+ __throw();
+}