1 // $XConsortium: Jump_Environment.hh /main/6 1996/10/04 09:35:47 drk $
4 #include "Unwind_Stack.hh"
6 class Jump_Environment : public Destructable
11 // Only unregister the environment if it hasn't been unregistered.
12 // It is unregistered when an exception is thrown and stack unwound.
15 static void register_object (Destructable *object);
16 static void unregister_object (Destructable *object);
18 static void unwind_and_jump (Exception *current, int debugging)
19 { g_jump_env_stack->do_unwind_and_jump (current, debugging); }
21 // Must be public so setjmp can be called on it. Can't use a
22 // method because of the way setjmp works.
25 // NOTE: this MUST follow f_env...mask bug in setjmp that overwrites our data
26 // 13:59 08/03/93 - jbm
32 { ::longjmp (f_env, 1); }
33 void do_register (Destructable *);
34 void do_unregister (Destructable *);
35 void do_unwind_and_jump (Exception *, int debugging);
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); }
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.
48 friend class Exceptions;
49 static Jump_Environment *g_jump_env_stack;
50 static Jump_Environment *g_used_jump_env_stack;
57 // /////////////////////////////////////////////////////////////////
59 // /////////////////////////////////////////////////////////////////
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.
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.
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
75 // If the stack is empty, it's the first object and can't be in another.
78 Jump_Environment::do_register (Destructable *object)
80 PRINTF ((" Considering object %p: ", object));
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()))
87 PRINTF ((" -- registered\n"));
88 f_unwind_stack.push (object, Destructable::g_size);
93 PRINTF ((" -- not registered\n"));
99 // /////////////////////////////////////////////////////////////////
101 // /////////////////////////////////////////////////////////////////
104 Jump_Environment::do_unregister (Destructable *object)
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)
111 PRINTF ((" -- removed\n"));
112 f_unwind_stack.pop();
117 PRINTF ((" -- never registered\n"));
124 // /////////////////////////////////////////////////////////////////
125 // register/unregister
126 // /////////////////////////////////////////////////////////////////
129 Jump_Environment::register_object (Destructable *object)
131 g_jump_env_stack->do_register (object);
135 Jump_Environment::unregister_object (Destructable *object)
137 g_jump_env_stack->do_unregister (object);