Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
139
cde/programs/dtinfo/DtMmdb/dti_excs/Jump_Environment.hh
Normal file
139
cde/programs/dtinfo/DtMmdb/dti_excs/Jump_Environment.hh
Normal file
@@ -0,0 +1,139 @@
|
||||
// $XConsortium: Jump_Environment.hh /main/6 1996/10/04 09:35:47 drk $
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "Unwind_Stack.hh"
|
||||
|
||||
class Jump_Environment : public Destructable
|
||||
{
|
||||
public:
|
||||
Jump_Environment();
|
||||
|
||||
// Only unregister the environment if it hasn't been unregistered.
|
||||
// It is unregistered when an exception is thrown and stack unwound.
|
||||
~Jump_Environment();
|
||||
|
||||
static void register_object (Destructable *object);
|
||||
static void unregister_object (Destructable *object);
|
||||
|
||||
static void unwind_and_jump (Exception *current, int debugging)
|
||||
{ g_jump_env_stack->do_unwind_and_jump (current, debugging); }
|
||||
|
||||
// Must be public so setjmp can be called on it. Can't use a
|
||||
// method because of the way setjmp works.
|
||||
jmp_buf f_env;
|
||||
#ifdef SVR4
|
||||
// NOTE: this MUST follow f_env...mask bug in setjmp that overwrites our data
|
||||
// 13:59 08/03/93 - jbm
|
||||
int f_filler[8] ;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void longjmp()
|
||||
{ ::longjmp (f_env, 1); }
|
||||
void do_register (Destructable *);
|
||||
void do_unregister (Destructable *);
|
||||
void do_unwind_and_jump (Exception *, int debugging);
|
||||
void delete_active();
|
||||
// The pending exception is the exception that is about to become
|
||||
// the current exception. It may be NULL if none has been thrown.
|
||||
static Exception *pending_exception()
|
||||
{ return (g_jump_env_stack->f_active_exception); }
|
||||
|
||||
private: // variables
|
||||
Exception *f_active_exception;
|
||||
Jump_Environment *f_next; // For Jump_Enviroment stacking.
|
||||
unsigned char f_unwinding; // True when unwind in progress.
|
||||
Unwind_Stack f_unwind_stack; // Stack of objects to unwind.
|
||||
|
||||
friend class Exceptions;
|
||||
static Jump_Environment *g_jump_env_stack;
|
||||
static Jump_Environment *g_used_jump_env_stack;
|
||||
#ifdef EXC_DEBUG
|
||||
static int g_level;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// do_register
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Register the object if it isn't a member of another Destructable
|
||||
// object. If it is a member of another, that object (or the object
|
||||
// that it's a member of) must be the last thing we registered.
|
||||
|
||||
// First check for downward growing stack. In this case the object
|
||||
// is part of another if it's address is greater than the start of
|
||||
// that other object. If it wasn't a member of that object, it's
|
||||
// address would have to be lower than that object, having been
|
||||
// created after that object.
|
||||
|
||||
// Second check for upward growing stack. In this case the object
|
||||
// is part of another if it's address is less than the end of that
|
||||
// other object.
|
||||
|
||||
// If the stack is empty, it's the first object and can't be in another.
|
||||
|
||||
inline void
|
||||
Jump_Environment::do_register (Destructable *object)
|
||||
{
|
||||
PRINTF ((" Considering object %p: ", object));
|
||||
|
||||
if (f_unwind_stack.empty() ||
|
||||
(Destructable::stack_grows_down() ?
|
||||
(unsigned long) object < f_unwind_stack.top().object_start() :
|
||||
(unsigned long) object > f_unwind_stack.top().object_end()))
|
||||
{
|
||||
PRINTF ((" -- registered\n"));
|
||||
f_unwind_stack.push (object, Destructable::g_size);
|
||||
}
|
||||
#ifdef EXC_DEBUG
|
||||
else
|
||||
{
|
||||
PRINTF ((" -- not registered\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// unregister_object
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void
|
||||
Jump_Environment::do_unregister (Destructable *object)
|
||||
{
|
||||
PRINTF ((" Unregister object @ %p: ", object));
|
||||
// Don't do anything it it wasn't on the stack. It must have been
|
||||
// part of another object or was never really constructed.
|
||||
if (!f_unwind_stack.empty() && f_unwind_stack.top().f_object == object)
|
||||
{
|
||||
PRINTF ((" -- removed\n"));
|
||||
f_unwind_stack.pop();
|
||||
}
|
||||
#ifdef EXC_DEBUG
|
||||
else
|
||||
{
|
||||
PRINTF ((" -- never registered\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// register/unregister
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void
|
||||
Jump_Environment::register_object (Destructable *object)
|
||||
{
|
||||
g_jump_env_stack->do_register (object);
|
||||
}
|
||||
|
||||
inline void
|
||||
Jump_Environment::unregister_object (Destructable *object)
|
||||
{
|
||||
g_jump_env_stack->do_unregister (object);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user