Jump_Environment.hh 5.0 KB

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