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: Jump_Environment.C /main/6 1996/10/04 09:37:00 drk $
24 #ifndef NATIVE_EXCEPTIONS
25 #include "Exceptions.hh"
27 Jump_Environment *Jump_Environment::g_jump_env_stack;
30 int Jump_Environment::g_level;
33 unsigned short Unwind_Stack::g_top ;
36 Unwind_Record* Unwind_Stack::g_stack = 0; // inited in init.C
38 Unwind_Record Unwind_Stack::g_stack[UNWIND_STACK_SIZE];
42 // /////////////////////////////////////////////////////////////////
43 // Jump_Environment - class constructor
44 // /////////////////////////////////////////////////////////////////
46 Jump_Environment::Jump_Environment()
47 : f_active_exception (NULL), f_unwinding (0)
49 PRINTF (("<%d> New Jump_Environment @ %p\n", ++g_level, this));
50 // Push this on to the top of the jump env stack.
51 f_next = g_jump_env_stack;
52 g_jump_env_stack = this;
55 // /////////////////////////////////////////////////////////////////
57 // /////////////////////////////////////////////////////////////////
59 Jump_Environment::~Jump_Environment()
61 // If g_jump_env_stack == this an exception wasn't thrown.
62 // (Because at throw time we set g_jump_env_stack to f_next.)
63 if (g_jump_env_stack == this)
65 g_jump_env_stack = f_next;
67 // An exception was thrown in our try block.
68 // An exception may have been thrown in our catch block.
69 // If one was, g_jump_env_stack->f_active_exception != NULL.
70 if (f_active_exception != NULL)
74 PRINTF (("<%d> Done with Jump_Environment @ %p\n",
79 // /////////////////////////////////////////////////////////////////
80 // unwind - call destructors for stack based objects
81 // /////////////////////////////////////////////////////////////////
84 Jump_Environment::do_unwind_and_jump (Exception *exception, int debugging)
86 PRINTF (("----- <%d> Unwinding stack -----\n", g_level));
88 // Remember the current exception so we can delete it later.
89 f_active_exception = exception;
91 // Check for a throw out of a destructor.
94 Exceptions::error (Exceptions::f_msg_throw_from_destructor,
95 Exceptions::APPLICATION_ERROR);
101 // Call the destructor of each objet on the stack in reverse.
102 // Length is automatically decremented as each object unregisters itself.
103 while (!f_unwind_stack.empty())
105 PRINTF (("* Calling dtor of %p\n", f_unwind_stack.top().f_object));
107 f_unwind_stack.top().f_object->destruct();
109 f_unwind_stack.top().f_object->~Destructable();
113 // This Jump Environment is no longer needed, so we need to pull it off
114 // the global jump env stack. Any new stack objects from this point
115 // on must be registed in the enclosing Jump Environment scope for the
116 // purposes of exceptions or otherwise. The memory associated with the
117 // unwind_stack is freed when we exit the scope or throw an exception.
118 g_jump_env_stack = f_next;
119 PRINTF (("----- <%d> Unwind complete -----\n", g_level));
121 // Make the current exception official (it may move in the process).
122 f_active_exception->make_current();
124 // Print a message about the throw point if debugging is on.
127 Exceptions::error_handler_t saved = Exceptions::set_error_handler (NULL);
128 Exceptions::error (NULL, Exceptions::THROW_MESSAGE);
129 Exceptions::set_error_handler (saved);
137 // /////////////////////////////////////////////////////////////////
138 // delete_active - delete active exception, maybe move pending
139 // /////////////////////////////////////////////////////////////////
142 Jump_Environment::delete_active()
144 // For starters, it's no longer the current exception.
145 f_active_exception->unmake_current();
147 // We normally delete the current exception when it's enclosing
148 // environment is destructed, UNLESS the same exception is being
149 // rethrown to the handler above. g_jump_env_stack points to
150 // the Jump_Environment that is unwinding.
152 if (f_active_exception->f_temporary &&
153 (g_jump_env_stack == NULL || f_active_exception != pending_exception()))
155 // If there's one pending we created and a current one, we are going
156 // to have to move the pending one down on our stack after
157 // deleting the current one, so we need to remember where it ends.
158 // If the pending exception == the current one, then we're just
159 // returning to the scope of a previous exception.
161 if (g_jump_env_stack != NULL &&
162 pending_exception() != NULL &&
163 pending_exception()->f_temporary &&
164 pending_exception() != Exception::g_current_exception)
166 // The length() method is only valid here!
167 int length = pending_exception()->length();
168 delete f_active_exception;
169 Exception::relocate (&g_jump_env_stack->f_active_exception,
172 else // Just delete it -- no move necessary.
174 delete f_active_exception;
178 #endif /* NATIVE_EXCEPTIONS */