2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 // $XConsortium: Exception.C /main/4 1996/10/04 09:40:25 drk $
24 #ifndef NATIVE_EXCEPTIONS
25 #include "Exceptions.hh"
28 Exception *Exception::g_current_exception;
31 char* Exception::g_temp_space = 0;
32 char *Exception::g_next_avail = 0;
34 char Exception::g_temp_space[G_TEMP_SPACE_SIZE];
35 char *Exception::g_next_avail = Exception::g_temp_space;
38 // /////////////////////////////////////////////////////////////////
40 // /////////////////////////////////////////////////////////////////
42 Exception::Exception()
43 : f_thrown(0), f_thrown_as_pointer(1), f_temporary(0), f_line(0)
45 PRINTF (("Constructed Exception obj @ %p\n", this));
49 // /////////////////////////////////////////////////////////////////
51 // /////////////////////////////////////////////////////////////////
54 Exception::operator delete (void *place)
56 // Move pointer back if it's in our temp space, else just free it.
57 if (place >= g_temp_space && place < g_temp_space + G_TEMP_SPACE_SIZE)
59 g_next_avail = (char *) place;
60 PRINTF (("De-alloc EXC @ %p\n", place));
64 free ((char *) place);
69 // /////////////////////////////////////////////////////////////////
71 // /////////////////////////////////////////////////////////////////
73 // int arg is only used for type matching to insure that our version
74 // of new gets called to make temporaries.
77 Exception::operator new (size_t size, int)
79 if (g_next_avail + size > g_temp_space + G_TEMP_SPACE_SIZE)
81 Exceptions::error (Exceptions::f_msg_out_of_exception_memory,
82 Exceptions::INTERNAL_ERROR);
86 void *p = g_next_avail;
88 PRINTF (("Allocate EXC @ %p, size = %ld\n", p, (long)size));
93 // /////////////////////////////////////////////////////////////////
95 // /////////////////////////////////////////////////////////////////
97 // According to ARM, 15.2c temporary object thrown is of the static
98 // type of the operand to throw, so this method must be non-virtual.
99 // A non-virtual version of this function is created with macros in
100 // each subclass of the Exception object. See Exception.hh.
103 Exception::throw_it (unsigned int line, const char *file, int dbg)
105 // NOTE: This is the only place we can detect a throw of a pointer
106 // to a stack based object.
109 PRINTF (("Preparing to throw Exception object at %p:\n", this));
111 // Only make a temporary if the exception object is on the stack.
114 PRINTF ((" Exception is on the stack - copying it\n"));
115 // Use the special new operator which allocates the exception
116 // in reserved storage if there's no memory available.
117 temp = new (0) Exception (*this);
118 // We created it, so we should delete it.
119 temp->f_temporary = 1;
123 PRINTF ((" Exception is on the heap\n"));
127 temp->do_throw (line, file, dbg);
131 // /////////////////////////////////////////////////////////////////
132 // throw - throw the current exception
133 // /////////////////////////////////////////////////////////////////
136 Exception::do_throw (unsigned int line, const char *file, int debugging)
141 PRINTF (("========== Throwing exception ==========\n"));
143 else // must be a rethrow
145 PRINTF (("========== Re-throwing exception ==========\n"));
149 // Save line and file if we don't already have it.
157 Jump_Environment::unwind_and_jump (this, debugging);
161 // /////////////////////////////////////////////////////////////////
162 // current_exception - return the current exception
163 // /////////////////////////////////////////////////////////////////
166 Exception::current_exception()
168 if (g_current_exception == NULL)
170 Exceptions::error (Exceptions::f_msg_no_current_exception,
171 Exceptions::APPLICATION_ERROR);
175 return (*g_current_exception);
179 // /////////////////////////////////////////////////////////////////
180 // (un)make_current - (un)make this exception the current one
181 // /////////////////////////////////////////////////////////////////
184 Exception::unmake_current()
186 PRINTF (("Current Exc POP %p <-- %p\n",
187 g_current_exception, f_previous_exception));
188 if (this != g_current_exception)
190 Exceptions::error ("Popped exception is the current one!",
191 Exceptions::INTERNAL_ERROR);
195 // Called when a catch clause is exited.
196 g_current_exception = f_previous_exception;
201 Exception::make_current()
203 PRINTF (("Current Exc PUSH --> %p\n", this));
204 f_previous_exception = g_current_exception;
205 g_current_exception = this;
209 // /////////////////////////////////////////////////////////////////
210 // relocate - move this exception to the current top of stack
211 // /////////////////////////////////////////////////////////////////
214 Exception::relocate (Exception **exception, int length)
216 PRINTF (("Moving %p --> %p (%d bytes)\n",
217 *exception, g_next_avail, length));
218 // Slide the specified exception down to fill the hole below it.
219 if (g_next_avail >= (char *) *exception)
221 memcpy (g_next_avail, (void*)*exception, length);
222 *exception = (Exception *) g_next_avail;
223 g_next_avail = ((char *) *exception) + length;
227 // /////////////////////////////////////////////////////////////////
228 // is - return true this class is of type TYPE
229 // /////////////////////////////////////////////////////////////////
232 Exception::is (const char *type, const char *this_class)
234 PRINTF (("Type specified is <%s>\n", type));
236 while (isalnum ((unsigned char) *type) &&
237 isalnum ((unsigned char) *this_class) &&
238 *type++ == *this_class++);
239 if (isalnum ((unsigned char) *type) ||
240 isalnum ((unsigned char) *this_class))
243 // Check for pointer types
244 while (isspace ((unsigned char) *type))
248 PRINTF ((" var part is <%s>\n", type));
250 // See if one's a pointer and the other isn't.
251 if ((*type == '*' && !f_thrown_as_pointer) ||
252 (*type != '*' && f_thrown_as_pointer))
254 // Otherwise they are either both pointers or both objects/references.
257 #endif /* NATIVE_EXCEPTIONS */