Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / dti_excs / Jump_Environment.hh
1 // $XConsortium: Jump_Environment.hh /main/6 1996/10/04 09:35:47 drk $
2 #include <setjmp.h>
3
4 #include "Unwind_Stack.hh"
5
6 class Jump_Environment : public Destructable
7 {
8 public:
9   Jump_Environment();
10
11   // Only unregister the environment if it hasn't been unregistered.
12   // It is unregistered when an exception is thrown and stack unwound. 
13   ~Jump_Environment();
14
15   static void register_object (Destructable *object);
16   static void unregister_object (Destructable *object);
17
18   static void unwind_and_jump (Exception *current, int debugging)
19     { g_jump_env_stack->do_unwind_and_jump (current, debugging); }
20
21   // Must be public so setjmp can be called on it.  Can't use a
22   // method because of the way setjmp works. 
23   jmp_buf            f_env;
24 #ifdef SVR4
25   // NOTE: this MUST follow f_env...mask bug in setjmp that overwrites our data
26   // 13:59 08/03/93 - jbm 
27   int                f_filler[8] ;
28 #endif
29
30 private:
31   void longjmp()
32     { ::longjmp (f_env, 1); }
33   void do_register (Destructable *);
34   void do_unregister (Destructable *);
35   void do_unwind_and_jump (Exception *, int debugging);
36   void delete_active();
37   // The pending exception is the exception that is about to become
38   // the current exception.  It may be NULL if none has been thrown. 
39   static Exception *pending_exception()
40     { return (g_jump_env_stack->f_active_exception); }
41
42 private: // variables
43   Exception         *f_active_exception;
44   Jump_Environment  *f_next;           // For Jump_Enviroment stacking.
45   unsigned char      f_unwinding;      // True when unwind in progress. 
46   Unwind_Stack       f_unwind_stack;   // Stack of objects to unwind.
47
48 friend class Exceptions;
49   static Jump_Environment *g_jump_env_stack;
50   static Jump_Environment *g_used_jump_env_stack;
51 #ifdef EXC_DEBUG
52   static int g_level;
53 #endif
54 };
55
56
57 // /////////////////////////////////////////////////////////////////
58 // do_register
59 // /////////////////////////////////////////////////////////////////
60
61 // Register the object if it isn't a member of another Destructable
62 // object.  If it is a member of another, that object (or the object
63 // that it's a member of) must be the last thing we registered.
64
65 // First check for downward growing stack.  In this case the object
66 // is part of another if it's address is greater than the start of
67 // that other object.  If it wasn't a member of that object, it's
68 // address would have to be lower than that object, having been 
69 // created after that object.
70
71 // Second check for upward growing stack.  In this case the object
72 // is part of another if it's address is less than the end of that
73 // other object.
74
75 // If the stack is empty, it's the first object and can't be in another.
76
77 inline void
78 Jump_Environment::do_register (Destructable *object)
79 {
80   PRINTF (("  Considering object %p: ", object));
81     
82   if (f_unwind_stack.empty() ||
83       (Destructable::stack_grows_down() ?
84        (unsigned long) object < f_unwind_stack.top().object_start() :
85        (unsigned long) object > f_unwind_stack.top().object_end()))
86     {
87       PRINTF ((" -- registered\n"));
88       f_unwind_stack.push (object, Destructable::g_size);
89     }
90 #ifdef EXC_DEBUG
91   else
92     {
93       PRINTF ((" -- not registered\n"));
94     }
95 #endif 
96 }
97
98
99 // /////////////////////////////////////////////////////////////////
100 // unregister_object
101 // /////////////////////////////////////////////////////////////////
102
103 inline void
104 Jump_Environment::do_unregister (Destructable *object)
105 {
106   PRINTF (("  Unregister object @ %p:  ", object));
107   // Don't do anything it it wasn't on the stack.  It must have been
108   // part of another object or was never really constructed. 
109   if (!f_unwind_stack.empty() && f_unwind_stack.top().f_object == object)
110     {
111       PRINTF ((" -- removed\n"));
112       f_unwind_stack.pop();
113     }
114 #ifdef EXC_DEBUG
115   else
116     {
117       PRINTF ((" -- never registered\n"));
118     }
119 #endif
120 }
121
122
123
124 // /////////////////////////////////////////////////////////////////
125 // register/unregister
126 // /////////////////////////////////////////////////////////////////
127
128 inline void
129 Jump_Environment::register_object (Destructable *object)
130 {
131   g_jump_env_stack->do_register (object);
132 }
133
134 inline void
135 Jump_Environment::unregister_object (Destructable *object)
136 {
137   g_jump_env_stack->do_unregister (object);
138 }
139