Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
// $XConsortium: Jump_Environment.C /main/6 1996/10/04 09:37:00 drk $
#ifndef NATIVE_EXCEPTIONS
#include "Exceptions.hh"
Jump_Environment *Jump_Environment::g_jump_env_stack;
#ifdef EXC_DEBUG
int Jump_Environment::g_level;
#endif
unsigned short Unwind_Stack::g_top ;
#ifdef C_API
Unwind_Record* Unwind_Stack::g_stack = 0; // inited in init.C
#else
Unwind_Record Unwind_Stack::g_stack[UNWIND_STACK_SIZE];
#endif
// /////////////////////////////////////////////////////////////////
// Jump_Environment - class constructor
// /////////////////////////////////////////////////////////////////
Jump_Environment::Jump_Environment()
: f_unwinding (0), f_active_exception (NULL)
{
PRINTF (("<%d> New Jump_Environment @ %p\n", ++g_level, this));
// Push this on to the top of the jump env stack.
f_next = g_jump_env_stack;
g_jump_env_stack = this;
}
// /////////////////////////////////////////////////////////////////
// class destructor
// /////////////////////////////////////////////////////////////////
Jump_Environment::~Jump_Environment()
{
// If g_jump_env_stack == this an exception wasn't thrown.
// (Because at throw time we set g_jump_env_stack to f_next.)
if (g_jump_env_stack == this)
{
g_jump_env_stack = f_next;
}
// An exception was thrown in our try block.
// An exception may have been thrown in our catch block.
// If one was, g_jump_env_stack->f_active_exception != NULL.
if (f_active_exception != NULL)
{
delete_active();
}
PRINTF (("<%d> Done with Jump_Environment @ %p\n",
g_level--, this));
}
// /////////////////////////////////////////////////////////////////
// unwind - call destructors for stack based objects
// /////////////////////////////////////////////////////////////////
void
Jump_Environment::do_unwind_and_jump (Exception *exception, int debugging)
{
PRINTF (("----- <%d> Unwinding stack -----\n", g_level));
// Remember the current exception so we can delete it later.
f_active_exception = exception;
// Check for a throw out of a destructor.
if (f_unwinding)
{
Exceptions::error (Exceptions::f_msg_throw_from_destructor,
Exceptions::APPLICATION_ERROR);
terminate();
}
f_unwinding = 1;
// Call the destructor of each objet on the stack in reverse.
// Length is automatically decremented as each object unregisters itself.
while (!f_unwind_stack.empty())
{
PRINTF (("* Calling dtor of %p\n", f_unwind_stack.top().f_object));
#if CC_VERSION < 30
f_unwind_stack.top().f_object->destruct();
#else
f_unwind_stack.top().f_object->~Destructable();
#endif
}
// This Jump Environment is no longer needed, so we need to pull it off
// the global jump env stack. Any new stack objects from this point
// on must be registed in the enclosing Jump Environment scope for the
// purposes of exceptions or otherwise. The memory associated with the
// unwind_stack is freed when we exit the scope or throw an exception.
g_jump_env_stack = f_next;
PRINTF (("----- <%d> Unwind complete -----\n", g_level));
// Make the current exception official (it may move in the process).
f_active_exception->make_current();
// Print a message about the throw point if debugging is on.
if (debugging)
{
Exceptions::error_handler_t saved = Exceptions::set_error_handler (NULL);
Exceptions::error (NULL, Exceptions::THROW_MESSAGE);
Exceptions::set_error_handler (saved);
}
// And away we go...
longjmp();
}
// /////////////////////////////////////////////////////////////////
// delete_active - delete active exception, maybe move pending
// /////////////////////////////////////////////////////////////////
void
Jump_Environment::delete_active()
{
// For starters, it's no longer the current exception.
f_active_exception->unmake_current();
// We normally delete the current exception when it's enclosing
// environment is destructed, UNLESS the same exception is being
// rethrown to the handler above. g_jump_env_stack points to
// the Jump_Environment that is unwinding.
if (f_active_exception->f_temporary &&
(g_jump_env_stack == NULL || f_active_exception != pending_exception()))
{
// If there's one pending we created and a current one, we are going
// to have to move the pending one down on our stack after
// deleting the current one, so we need to remember where it ends.
// If the pending exception == the current one, then we're just
// returning to the scope of a previous exception.
if (g_jump_env_stack != NULL &&
pending_exception() != NULL &&
pending_exception()->f_temporary &&
pending_exception() != Exception::g_current_exception)
{
// The length() method is only valid here!
int length = pending_exception()->length();
delete f_active_exception;
Exception::relocate (&g_jump_env_stack->f_active_exception,
length);
}
else // Just delete it -- no move necessary.
{
delete f_active_exception;
}
}
}
#endif /* NATIVE_EXCEPTIONS */