source: trunk/gcc/libjava/exception.cc@ 3186

Last change on this file since 3186 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.1 KB
Line 
1// Functions for Exception Support for Java.
2
3/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11#include <config.h>
12
13#include <stddef.h>
14#include <stdlib.h>
15
16#include <java/lang/Class.h>
17#include <java/lang/NullPointerException.h>
18#include <gcj/cni.h>
19#include <jvm.h>
20
21// unwind-pe.h uses std::abort(), but sometimes we compile libjava
22// without libstdc++-v3. The following hack forces it to use
23// stdlib.h's abort().
24namespace std
25{
26 static __attribute__ ((__noreturn__)) void
27 abort ()
28 {
29 ::abort ();
30 }
31}
32#include "unwind.h"
33
34struct alignment_test_struct
35{
36 char space;
37 char end[0] __attribute__((aligned));
38};
39
40struct java_exception_header
41{
42 /* Cache handler details between Phase 1 and Phase 2. */
43 _Unwind_Ptr landingPad;
44 int handlerSwitchValue;
45
46 /* The object being thrown. Compiled code expects this to be immediately
47 before the generic exception header. Which is complicated by the fact
48 that _Unwind_Exception is ((aligned)). */
49
50 char pad[sizeof(jthrowable) < sizeof(alignment_test_struct)
51 ? sizeof(alignment_test_struct) - sizeof(jthrowable) : 0]
52 __attribute__((aligned));
53
54 jthrowable value;
55
56 /* The generic exception header. */
57 _Unwind_Exception unwindHeader;
58};
59
60// This is the exception class we report -- "GNUCJAVA".
61const _Unwind_Exception_Class __gcj_exception_class
62= ((((((((_Unwind_Exception_Class) 'G'
63 << 8 | (_Unwind_Exception_Class) 'N')
64 << 8 | (_Unwind_Exception_Class) 'U')
65 << 8 | (_Unwind_Exception_Class) 'C')
66 << 8 | (_Unwind_Exception_Class) 'J')
67 << 8 | (_Unwind_Exception_Class) 'A')
68 << 8 | (_Unwind_Exception_Class) 'V')
69 << 8 | (_Unwind_Exception_Class) 'A');
70
71
72static inline java_exception_header *
73get_exception_header_from_ue (_Unwind_Exception *exc)
74{
75 return reinterpret_cast<java_exception_header *>(exc + 1) - 1;
76}
77
78/* Perform a throw, Java style. Throw will unwind through this call,
79 so there better not be any handlers or exception thrown here. */
80
81extern "C" void
82_Jv_Throw (jthrowable value)
83{
84 java_exception_header *xh
85 = static_cast<java_exception_header *>(_Jv_AllocRawObj (sizeof (*xh)));
86
87 if (value == NULL)
88 value = new java::lang::NullPointerException ();
89 xh->value = value;
90
91 xh->unwindHeader.exception_class = __gcj_exception_class;
92 xh->unwindHeader.exception_cleanup = NULL;
93
94 /* We're happy with setjmp/longjmp exceptions or region-based
95 exception handlers: entry points are provided here for both. */
96 _Unwind_Reason_Code code;
97#ifdef SJLJ_EXCEPTIONS
98 code = _Unwind_SjLj_RaiseException (&xh->unwindHeader);
99#else
100 code = _Unwind_RaiseException (&xh->unwindHeader);
101#endif
102
103 /* If code == _URC_END_OF_STACK, then we reached top of stack without
104 finding a handler for the exception. Since each thread is run in
105 a try/catch, this oughtn't happen. If code is something else, we
106 encountered some sort of heinous lossage from which we could not
107 recover. As is the way of such things, almost certainly we will have
108 crashed before now, rather than actually being able to diagnose the
109 problem. */
110 abort();
111}
112
113
114
115#include "unwind-pe.h"
116
117
118struct lsda_header_info
119{
120 _Unwind_Ptr Start;
121 _Unwind_Ptr LPStart;
122 const unsigned char *TType;
123 const unsigned char *action_table;
124 unsigned char ttype_encoding;
125 unsigned char call_site_encoding;
126};
127
128static const unsigned char *
129parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
130 lsda_header_info *info)
131{
132 _Unwind_Word tmp;
133 unsigned char lpstart_encoding;
134
135 info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
136
137 // Find @LPStart, the base to which landing pad offsets are relative.
138 lpstart_encoding = *p++;
139 if (lpstart_encoding != DW_EH_PE_omit)
140 p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);