Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.7 KiB

  1. /***
  2. *ehvecdtr.cxx - EH-aware version of destructor iterator helper function
  3. *
  4. * Copyright (c) 1990-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * These functions are called when constructing and destructing arrays of
  8. * objects. Their purpose is to assure that constructed elements get
  9. * destructed if the constructor for one of the elements throws.
  10. *
  11. * Must be compiled using "-d1Binl" to be able to specify __thiscall
  12. * at the user level
  13. *
  14. *Revision History:
  15. * 10-11-93 JDR Module created
  16. * 05-09-94 BES Module adapted for CRT source conventions
  17. * 05-13-94 SKS Remove _CRTIMP modifier
  18. * 10-10-94 CFW Fix EH/SEH exception handling.
  19. * 10-17-94 BWT Disable code for PPC.
  20. * 11-09-94 CFW Back out 10-10-94 change.
  21. * 02-08-95 JWM Mac merge.
  22. * 04-14-95 JWM Re-fix EH/SEH exception handling.
  23. * 04-17-95 JWM Restore non-WIN32 behavior.
  24. * 04-27-95 JWM EH_ABORT_FRAME_UNWIND_PART now #ifdef ALLOW_UNWIND_ABORT.
  25. * 05-17-99 PML Remove all Macintosh support.
  26. * 05-20-99 PML Turn off __thiscall for IA64.
  27. * 07-12-99 RDL Image relative fixes under CC_P7_SOFT25.
  28. * 03-15-00 PML Remove CC_P7_SOFT25, which is now on permanently.
  29. * 12-07-01 BWT Remove NTSUBSET
  30. *
  31. ****/
  32. #include <cruntime.h>
  33. #include <ehdata.h>
  34. #include <eh.h>
  35. #if defined (_M_IX86)
  36. #define CALLTYPE __thiscall
  37. #else
  38. #define CALLTYPE __stdcall
  39. #endif
  40. #ifdef _WIN32
  41. void __stdcall __ArrayUnwind(
  42. void* ptr, // Pointer to array to destruct
  43. size_t size, // Size of each element (including padding)
  44. int count, // Number of elements in the array
  45. void(CALLTYPE *pDtor)(void*) // The destructor to call
  46. );
  47. void __stdcall __ehvec_dtor(
  48. void* ptr, // Pointer to array to destruct
  49. size_t size, // Size of each element (including padding)
  50. int count, // Number of elements in the array
  51. void(CALLTYPE *pDtor)(void*) // The destructor to call
  52. ){
  53. int success = 0;
  54. // Advance pointer past end of array
  55. ptr = (char*)ptr + size*count;
  56. __try
  57. {
  58. // Destruct elements
  59. while ( --count >= 0 )
  60. {
  61. ptr = (char*)ptr - size;
  62. (*pDtor)(ptr);
  63. }
  64. success = 1;
  65. }
  66. __finally
  67. {
  68. if (!success)
  69. __ArrayUnwind(ptr, size, count, pDtor);
  70. }
  71. }
  72. static int ArrayUnwindFilter(EXCEPTION_POINTERS* pExPtrs)
  73. {
  74. EHExceptionRecord *pExcept = (EHExceptionRecord*)pExPtrs->ExceptionRecord;
  75. switch(PER_CODE(pExcept))
  76. {
  77. case EH_EXCEPTION_NUMBER:
  78. terminate();
  79. #ifdef ALLOW_UNWIND_ABORT
  80. case EH_ABORT_FRAME_UNWIND_PART:
  81. return EXCEPTION_EXECUTE_HANDLER;
  82. #endif
  83. default:
  84. return EXCEPTION_CONTINUE_SEARCH;
  85. }
  86. }
  87. void __stdcall __ArrayUnwind(
  88. void* ptr, // Pointer to array to destruct
  89. size_t size, // Size of each element (including padding)
  90. int count, // Number of elements in the array
  91. void(CALLTYPE *pDtor)(void*) // The destructor to call
  92. ){
  93. // 'unwind' rest of array
  94. __try
  95. {
  96. while ( --count >= 0 )
  97. {
  98. ptr = (char*) ptr - size;
  99. (*pDtor)(ptr);
  100. }
  101. }
  102. __except( ArrayUnwindFilter(exception_info()) )
  103. {
  104. }
  105. }
  106. #else
  107. void __stdcall __ehvec_dtor(
  108. void* ptr, // Pointer to array to destruct
  109. unsigned size, // Size of each element (including padding)
  110. int count, // Number of elements in the array
  111. void(CALLTYPE *pDtor)(void*) // The destructor to call
  112. ){
  113. // Advance pointer past end of array
  114. ptr = (char*)ptr + size*count;
  115. try
  116. {
  117. // Destruct elements
  118. while ( --count >= 0 )
  119. {
  120. ptr = (char*)ptr - size;
  121. (*pDtor)(ptr);
  122. }
  123. }
  124. catch(...)
  125. {
  126. // If a destructor throws an exception, unwind the rest of this
  127. // array
  128. while ( --count >= 0 )
  129. {
  130. ptr = (char*) ptr - size;
  131. try {
  132. (*pDtor)(ptr);
  133. }
  134. catch(...) {
  135. // If any destructor throws during unwind, terminate
  136. terminate();
  137. }
  138. }
  139. // After array is unwound, rethrow the exception so a user's handler
  140. // can handle it.
  141. throw;
  142. }
  143. }
  144. #endif